21

How does a python programmer check if any value of a dictionary matches a condition (is greater than 0 in my case). I'm looking for the most "pythonic" way that has minimal performance-impact.

my dictionary:

pairs = { 'word1':0, 'word2':0, 'word3':2000, 'word4':64, 'word5':0, 'wordn':8 }

I used these 2 (monstrous?) methods so far.

1:

options = pairs.values() # extract values
for i in options:
    if i > 0:
        return True
return False

2:

options = sorted(pairs.items(), key=lambda e: e[1], reverse=True) # rank from max to min
if options[0][1] > 0:
    return True
else:
    return False
Firebowl2000
  • 302
  • 1
  • 2
  • 9
  • Are you checking just one entry in the dictionary (like your text says) or all entries (like your code is doing)? – smcg Sep 11 '12 at 18:55
  • @smcg: Sorry for my English. I meant all the entries;] – Firebowl2000 Sep 11 '12 at 18:56
  • The `.values` of the dictionary are a sequence; `any` accepts a sequence; thus we can use the same technique as in the linked duplicate (which is also the given answer here). – Karl Knechtel Aug 02 '22 at 23:38

2 Answers2

34

You can use any [docs]:

>>> pairs = { 'word1':0, 'word2':0, 'word3':2000, 'word4':64, 'word5':0, 'wordn':8 }
>>> any(v > 0 for v in pairs.itervalues())
True
>>> any(v > 3000 for v in pairs.itervalues())
False

See also all [docs]:

>>> all(v > 0 for v in pairs.itervalues())
False
>>> all(v < 3000 for v in pairs.itervalues())
True

Since you're using Python 2.7, .itervalues() is probably a little better than .values() because it doesn't create a new list.

DSM
  • 342,061
  • 65
  • 592
  • 494
  • 1
    I would go as far as saying this is _the_ pythonic way for doing this. – Lukas Graf Sep 11 '12 at 19:18
  • I often wonder how much difference there really is between `.values` and `.itervalues` -- After all, you're not creating new objects, only new references ... I suppose it's worth asking how much memory a python reference actually takes ... (I usually just use `values` since that won't need to be changed when I move my code to py3k ... but maybe I shouldn't ...) Good answer though. This is definitely the way to go about this (+1) – mgilson Sep 11 '12 at 19:29
  • @mgilson: Yeah, I tend to write `.values()` myself unless I have some reason to want the performance gain (I usually only see tens of percent) or the dictionary is really big. But whenever I don't use it someone comments on it, so you can't win. ;-) – DSM Sep 11 '12 at 19:43
  • Also see [PIE802](https://beta.ruff.rs/docs/rules/unnecessary-comprehension-any-all/) – Matthias Arras Apr 20 '23 at 07:49
1
Python 3.x Update

In Python 3, direct iteration over mappings works the same way as it does in Python 2. There are no method based equivalents - the semantic equivalents of d.itervalues() and d.iteritems() in Python 3 are iter(d.values()) and iter(d.items()).

According to the docs, you should use iter(d.values()), instead of d.itervalues():

>>> pairs = { 'word1':0, 'word2':0, 'word3':2000, 'word4':64, 'word5':0, 'wordn':8 }
>>> any(v > 0 for v in iter(pairs.values()))
True
>>> any(v > 3000 for v in iter(pairs.values()))
False
Pepe
  • 454
  • 5
  • 18