What approach should I use to return all dict keys that have the maximum value.
The code below outputs 1, but I would like for it to return 1, 2.

import operator
d1 = dict()
d1[0] = 1
d1[1] = 2
d1[2] = 2
maxValue = max(d1.iteritems(), key=operator.itemgetter(1))[0]

Like this seems to work, but I do not know if it is easiest. If you use Python 3, surely there must be cleaner alternative using dictionary comprehensions.

import operator
d1 = dict()
d1[0] = 1
d1[1] = 2
d1[2] = 2
maxValue = max(d1)
print [key for key in d1.keys() if d1[key]==maxValue]
""" Output:
[1, 2]
"""

Edited 6 Years Ago by pyTony: n/a

Like this seems to work, but I do not know if it is easiest. If you use Python 3, surely there must be cleaner alternative using dictionary comprehensions.

import operator
d1 = dict()
d1[0] = 1
d1[1] = 2
d1[2] = 2
maxValue = max(d1)
print [key for key in d1.keys() if d1[key]==maxValue]
""" Output:
[1, 2]
"""

I don't think that works ...

import operator
d1 = dict()
d1[0] = 1
d1[1] = 8
d1[2] = 8
maxValue = max(d1)
print [key for key in d1.keys() if d1[key]==maxValue]
""" Output:
[]   oops!
"""

Should be this:

d1 = dict()
d1[0] = 1
d1[1] = 8
d1[2] = 8
maxValue = max(d1.values())  #<-- max of values
print [key for key in d1 if d1[key]==maxValue]

Edited 6 Years Ago by jcao219: n/a

I don't think that works ...

import operator
d1 = dict()
d1[0] = 1
d1[1] = 8
d1[2] = 8
maxValue = max(d1)
print [key for key in d1.keys() if d1[key]==maxValue]
""" Output:
[]   oops!
"""

Was working by the given example, but actually it returns the maximum key instead of maximum value. When dictionary has with that key value that is not in keys of dictionary, the list comprehension returns empty list.

jcao219 gave proper fix and also took out the left over import which is not needed after the coding change ie max(dl.values()) Relatedly it took me quite a while to understand that to loop over all items in for cleanest way is:

for key,value in d1.items():
    print("d1[%s] = %s" % (key,value))

By the way, does anybody know how to define function to do this:

my_long_variable_name='Some value'
print(the_function(my_long_variable_name))

""" Output:
my_long_variable_name = 'Some value'
"""

Edited 6 Years Ago by pyTony: n/a

To get the external argument name of a function you can use dictionary globals() and id() ...

def the_function(arg):
    s = [key for key in globals() if id(globals()[key])==id(arg)][0]
    value = arg
    return "%s = %s" % (s, value)

my_long_variable_name = 'Some value'
print(the_function(my_long_variable_name))

"""Result >>>
my_long_variable_name = 'Some value'
"""

Edited 6 Years Ago by vegaseat: n/a

Comments
Good code for debugging from my request

I had guess of direction of where could solve the code, but as I have not experience of using the globals dict myself, I thought better to ask.

Thanks, vegaseat. the_function I think to name variable_info. It should be very useful in saving from typos and too much typing during debugging.

Had to change it little though to produce the output in my machine adding repr():

def variable_info(arg):
    s = [key for key in globals() if id(globals()[key])==id(arg)][0]
    value = arg
    return "%s = %s" % (s, repr(value))

my_long_variable_name = 'Some value'
print(variable_info(my_long_variable_name))

"""Result >>>
my_long_variable_name = 'Some value'
"""

Edited 6 Years Ago by pyTony: n/a

Sorry, I had originally eval(s) for a complete test. It's simpler to use just %r ...

def the_function(arg):
    s = [key for key in globals() if id(globals()[key])==id(arg)][0]
    value = arg  # or eval(s) for testing
    return "%s = %r" % (s, value)

my_long_variable_name = 'Some value'
print(the_function(my_long_variable_name))

"""Result >>>
my_long_variable_name = 'Some value'
"""

Another basic thing not learned about Python less! Sometimes must dig in to this id, it looks interesting.

BTW is there standard function for doing nothing, that is just return the parameter

nothing_function=lambda x: x

Seems little stupid to need to put such construct as default function parameter (see the Sudoku snippet from this clever Lisp (my first love language :) ) guy.

Eleagant and fast Sudoku with generator expressions

Sorry, I had originally eval(s) for a complete test. It's simpler to use just %r ...

def the_function(arg):
    s = [key for key in globals() if id(globals()[key])==id(arg)][0]
    value = arg  # or eval(s) for testing
    return "%s = %r" % (s, value)

my_long_variable_name = 'Some value'
print(the_function(my_long_variable_name))

"""Result >>>
my_long_variable_name = 'Some value'
"""

Unfortunately the technique does not apply to local variable:

def variable_info(arg):
    s = tuple(key for key in globals() if id(globals()[key])==id(arg))
    return ' = '.join(s + (repr(arg),))

def my_func():
    my_long_variable_name = 'Other value'
    print(variable_info(my_long_variable_name))

my_long_variable_name = 'Some value'
print(variable_info(my_long_variable_name))

my_func()

""" Output:
my_long_variable_name = 'Some value'
'Other value'
"""
This question has already been answered. Start a new discussion instead.