Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Dictionary with lists as values - find longest list

I have a dictionary where the values are lists. I need to find which key has the longest list as value, after removing the duplicates. If i just find the longest list this won't work as there may be a lot of duplicates. I have tried several things, but nothing is remotely close to being correct.

like image 994
user2795095 Avatar asked Feb 17 '14 21:02

user2795095


Video Answer


2 Answers

d = # your dictionary of lists

max_key = max(d, key= lambda x: len(set(d[x])))
# here's the short version. I'll explain....

max( # the function that grabs the biggest value
    d, # this is the dictionary, it iterates through and grabs each key...
    key = # this overrides the default behavior of max
        lambda x: # defines a lambda to handle new behavior for max
            len( # the length of...
                set( # the set containing (sets have no duplicates)
                    d[x] # the list defined by key `x`
                   )
               )
   )

Since the code for max iterates through the dictionaries' keys (that's what a dictionary iterates through, by the by. for x in dict: print x will print each key in dict) it will return the key that it finds to have the highest result when it applies the function we built (that's what the lambda does) for key=. You could literally do ANYTHING here, that's the beauty of it. However, if you wanted the key AND the value, you might be able to do something like this....

d = # your dictionary

max_key, max_value = max(d.items(), key = lambda k,v: len(set(v)))
# THIS DOESN'T WORK, SEE MY NOTE AT BOTTOM

This differs because instead of passing d, which is a dictionary, we pass d.items(), which is a list of tuples built from d's keys and values. As example:

d = {"foo":"bar", "spam":['green','eggs','and','ham']}
print(d.items())
# [ ("foo", "bar"),
#   ("spam", ["green","eggs","and","ham"])]

We're not looking at a dictionary anymore, but all the data is still there! It makes it easier to deal with using the unpack statement I used: max_key, max_value =. This works the same way as if you did WIDTH, HEIGHT = 1024, 768. max still works as usual, it iterates through the new list we built with d.items() and passes those values to its key function (the lambda k,v: len(set(v))). You'll also notice we don't have to do len(set(d[k])) but instead are operating directly on v, that's because d.items() has already created the d[k] value, and using lambda k,v is using that same unpack statement to assign the key to k and the value to v.

Magic! Magic that doesn't work, apparently. I didn't dig deep enough here, and lambdas cannot, in fact, unpack values on their own. Instead, do:

max_key, max_value = max(d.items(), key = lambda x: len(set(x[1])))
like image 101
Adam Smith Avatar answered Sep 28 '22 00:09

Adam Smith


for less advanced user this can be a solution:

longest = max(len(item) for item in your_dict.values())
result = [item for item in your_dict.values() if len(item) == longest]
like image 33
Alkindus Avatar answered Sep 28 '22 01:09

Alkindus