has_key or in

来源:互联网 发布:倩女幽魂mac可以玩吗 编辑:程序博客网 时间:2024/06/08 19:35

'has_key()' or 'in'?

up vote393down votefavorite
51

I wonder what is better to do:

d = {'a': 1, 'b': 2}'a' in dTrue

or:

d = {'a': 1, 'b': 2}d.has_key('a')True
shareimprove this question
 

11 Answers

activeoldestvotes
up vote546down voteaccepted

in is definitely more pythonic.

In fact has_key() was removed in Python 3.x.

shareimprove this answer
 
2 
As an addition, in Python 3, to check for the existence in values, instead of the keys, try >>> 1 in d.values() – riza Aug 24 '09 at 18:12
76 
One semi-gotcha to avoid though is to make sure you do: "key in some_dict" rather than "key in some_dict.keys()". Both are equivalent semantically, but performance-wise the latter is much slower (O(n) vs O(1)). I've seen people do the "in dict.keys()" thinking it's more explicit & therefore better. – Adam Parkin Nov 9 '11 at 20:55
1 
in works with 2.6 too right? – Logan Jan 17 '13 at 4:07
 
@Logan yes it does – Wax Cage Jul 3 '15 at 13:10
1 
@BenjaminSchollnick what's the result? – DerekY Dec 14 '15 at 10:01
up vote179down vote

in wins hands-down, not just in elegance (and not being deprecated;-) but also in performance, e.g.:

$ python -mtimeit -s'd=dict.fromkeys(range(99))' '12 in d'10000000 loops, best of 3: 0.0983 usec per loop$ python -mtimeit -s'd=dict.fromkeys(range(99))' 'd.has_key(12)'1000000 loops, best of 3: 0.21 usec per loop

While the following observation is not always true, you'll notice that usually, in Python, the faster solution is more elegant and Pythonic; that's why -mtimeit is SO helpful -- it's not just about saving a hundred nanoseconds here and there!-)

shareimprove this answer
 
2 
thanks a lot, good to know, now I'm changing my code to use 'in' instead of has_key() ;) – igorgue Aug 24 '09 at 18:56
3 
Thanks for this, made verifying that "in some_dict" is in fact O(1) much easier (try increasing the 99 to say 1999, and you'll find the runtime is about the same). – Adam Parkin Nov 9 '11 at 21:00
 
has_key appears to be O(1) too. – dan-gph Jan 6 '15 at 4:11
up vote43down vote

According to python docs:

has_key() is deprecated in favor of key in d.

shareimprove this answer
 
 
thanks a lot, it really helped! – Aaron Socurites Aug 19 '15 at 7:17
up vote28down vote

Use dict.has_key() if (and only if) your code is required to be runnable by Python versions earlier than 2.3 (when key in dict was introduced). 

shareimprove this answer
 
6 
While one would hope no one is using a Python earlier than 2.3 (released in 2003), I'm quite confident there are still some holdouts. So this answer is a valuable footnote to all the "use in of course, duh" answers. – John Y Aug 3 '11 at 21:07
2 
@JohnY This really comes into play with the embedded linux variants. I'm currently stuck using 2.3 on two projects :( – Adam Lewis Feb 23 '13 at 23:37
1 
The WebSphere update in 2013 uses Jython 2.1 as its main scripting language. So this is unfortunately still a useful thing to note, five years after you noted it. – ArtOfWarfare Sep 24 '14 at 11:49
up vote13down vote

There is one example where in actually kills your performance.

If you use in on a O(1) container that only implements __getitem__ and has_key() but not __contains__ you will turn an O(1) search into an O(N) search (as in falls back to a linear search via __getitem__).

Fix is obviously trivial:

def __contains__(self, x):    return self.has_key(x)
shareimprove this answer
 
up vote8down vote

has_key is a dictionary method, but in will work on any collection, and even when __contains__ is missing, in will use any other method to iterate the collection to find out.

shareimprove this answer
0 0