How to filter dictionary keys based on its corresponding values

I have:

dictionary = {"foo":12, "bar":2, "jim":4, "bob": 17} 

I want to iterate over this dictionary, but above the values ​​instead of the keys, so I can use the values ​​in another function.

For example, I want to check which dictionary values ​​are greater than 6 , and then save their keys in a list. My code is as follows:

 list = [] for c in dictionary: if c > 6: list.append(dictionary[c]) print list 

and then in the ideal world of list all keys with a value greater than 6 will be displayed. However, my for loop only iterates over the keys; I would like to change this to values!

Any help is appreciated. thank

+57
python dictionary
May 08 '12 at 11:57
source share
6 answers
 >>> d = {"foo": 12, "bar": 2, "jim": 4, "bob": 17} >>> [k for k, v in d.items() if v > 6] # Use d.iteritems() on python 2.x ['bob', 'foo'] 



I would just like to update this answer to also demonstrate the @glarrain solution, which I consider it my duty to use.

 [k for k in d if d[k] > 6] 

This is fully cross-compatible and does not require a vague change from .iteritems ( .iteritems avoids storing the list in memory in Python 2, which is fixed in Python 3), to .items .

@ Prof. Falken mentioned a solution to this problem

 from six import iteritems 

which effectively fixes BUT cross-compatibility issues requires you to download the six package

However, I do not completely agree with @glarrain that this solution is more readable, this is a discussion and, perhaps, only a personal preference, although Python should have only one way to do this. In my opinion, this depends on the situation (for example, you may have a long dictionary name that you do not want to enter twice, or you want the values ​​to become a more readable name or some other reason).

Some interesting timings:

In Python 2, the second solution is faster; in Python 3, they are almost exactly equal in speed.




 $ python -m timeit -s 'd = {"foo": 12, "bar": 2, "jim": 4, "bob": 17};' '[k for k, v in d.items() if v > 6]' 1000000 loops, best of 3: 0.772 usec per loop $ python -m timeit -s 'd = {"foo": 12, "bar": 2, "jim": 4, "bob": 17};' '[k for k, v in d.iteritems() if v > 6]' 1000000 loops, best of 3: 0.508 usec per loop $ python -m timeit -s 'd = {"foo": 12, "bar": 2, "jim": 4, "bob": 17};' '[k for k in d if d[k] > 6]' 1000000 loops, best of 3: 0.45 usec per loop $ python3 -m timeit -s 'd = {"foo": 12, "bar": 2, "jim": 4, "bob": 17};' '[k for k, v in d.items() if v > 6]' 1000000 loops, best of 3: 1.02 usec per loop $ python3 -m timeit -s 'd = {"foo": 12, "bar": 2, "jim": 4, "bob": 17};' '[k for k in d if d[k] > 6]' 1000000 loops, best of 3: 1.02 usec per loop 

However, these are only tests for small dictionaries, in huge dictionary words, I am sure that without searching for the dictionary key ( d[k] ), I would make .items much faster. And it looks like this.

 $ python -m timeit -s 'd = {i: i for i in range(-10000000, 10000000)};' -n 1 '[k for k in d if d[k] > 6]' 1 loops, best of 3: 1.75 sec per loop $ python -m timeit -s 'd = {i: i for i in range(-10000000, 10000000)};' -n 1 '[k for k, v in d.iteritems() if v > 6]' 1 loops, best of 3: 1.71 sec per loop $ python3 -m timeit -s 'd = {i: i for i in range(-10000000, 10000000)};' -n 1 '[k for k in d if d[k] > 6]' 1 loops, best of 3: 3.08 sec per loop $ python3 -m timeit -s 'd = {i: i for i in range(-10000000, 10000000)};' -n 1 '[k for k, v in d.items() if v > 6]' 1 loops, best of 3: 2.47 sec per loop 
+81
May 08 '12 at 11:59
source share

To simply get the values, use dictionary.values()

To get key value pairs, use dictionary.items()

+36
May 08 '12 at 12:00
source share

Use the items dictionary or iteritems in the dictionary. Something like:

 list = [] for k, v in dictionary.iteritems(): if v > 6: list.append(k) print list 
+10
May 8 '12 at 12:01
source share

How about this:

 dictionary = {"foo":12, "bar":2, "jim":4, "bob": 17} for val in dictionary.values(): # do something 
+4
May 08 '12 at 12:00
source share

It depends on whether you want to change the dictionary (add or remove items) or not. If not, you can try:

 for value in dictionary.itervalues(): #this returns a generator print "do something with the value" 

Alternatively, if you modify the dictionary, you should iterate over a copy of the values:

 for value in dictionary.values(): #this returns a list of values print "do something with the value" 

If you need both keys and values, you can iterate over pairs using dictionary.iteritems() or dictionary.items()

+2
May 8 '12 at 12:03
source share

I think the best way to do this (given the switch to Python 3) is to

 >>> mydict = {'foo': 12, 'bar': 2, 'jim': 4, 'bob': 17} >>> [k for k in mydict if mydict[k] > 6] ['bob', 'foo'] 

The β€œbest” criteria are readability.

(Disclaimer: my answer is based on Alex Martelli, responding to another question https://stackoverflow.com/a/2126185/ and @jamylak to this question)

+2
May 28 '13 at 14:42
source share



All Articles