Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Python best way to check for existing key

Tags:

python

Which is the more efficient/faster/better way to check if a key exists?

if 'subject' in request.POST:
    subject = request.POST['subject']
else:
    // handle error

OR

try:
    subject = request.POST['subject']
except KeyError:
    // handle error
like image 876
mhost Avatar asked Feb 11 '10 20:02

mhost


People also ask

How do you check if a key already exists?

Check If Key Exists Using has_key() The has_key() method is a built-in method in Python that returns true if the dict contains the given key, and returns false if it isn't.

How do I search for a key in Python?

To simply check if a key exists in a Python dictionary you can use the in operator to search through the dictionary keys like this: pets = {'cats': 1, 'dogs': 2, 'fish': 3} if 'dogs' in pets: print('Dogs found!') # Dogs found! A dictionary can be a convenient data structure for counting the occurrence of items.

How do you check if a key-value pair exists in a dictionary Python?

To check if a key-value pair exists in a dictionary, i.e., if a dictionary has/contains a pair, use the in operator and the items() method. Specify a tuple (key, value) . Use not in to check if a pair does not exist in a dictionary.


3 Answers

The latter (try/except) form is generally the better form.

try blocks are very cheap but catching an exception can be more expensive. A containment check on a dict tends to be cheap, but not cheaper than nothing. I suspect there will be a balance of efficiency depending on how often 'subject' is really there. However, this doesn't matter, since premature optimization is useless, distracting, wasteful, and ineffective. You would go with the better solution.

If the code would actually be of the form

if 'subject' in request.POST:     subject = request.POST['subject'] else:     subject = some_default 

then what you actually want is request.POST.get('subject', some_default).

like image 131
Mike Graham Avatar answered Oct 19 '22 17:10

Mike Graham


I use .get() method — it is preferable method.

Python 2.5.2 (r252:60911, Jul 22 2009, 15:33:10) [GCC 4.2.4 (Ubuntu 4.2.4-1ubuntu3)] on linux2 Type "help", "copyright", "credits" or "license" for more information. >>> import dis >>> def f1(key, d): ...   if key in d: ...     return d[key] ...   else: ...     return "default" ... >>> dis.dis(f1)   2           0 LOAD_FAST                0 (key)               3 LOAD_FAST                1 (d)               6 COMPARE_OP               6 (in)               9 JUMP_IF_FALSE           12 (to 24)              12 POP_TOP    3          13 LOAD_FAST                1 (d)              16 LOAD_FAST                0 (key)              19 BINARY_SUBSCR              20 RETURN_VALUE              21 JUMP_FORWARD             5 (to 29)         >>   24 POP_TOP    5          25 LOAD_CONST               1 ('default')              28 RETURN_VALUE         >>   29 LOAD_CONST               0 (None)              32 RETURN_VALUE >>> def f2(key, d): ...   return d.get(key, "default") ... >>> dis.dis(f2)   2           0 LOAD_FAST                1 (d)               3 LOAD_ATTR                0 (get)               6 LOAD_FAST                0 (key)               9 LOAD_CONST               1 ('default')              12 CALL_FUNCTION            2              15 RETURN_VALUE >>> def f3(key, d): ...   try: ...     return d[key] ...   except KeyError: ...     return "default" ... >>> dis.dis(f3)   2           0 SETUP_EXCEPT            12 (to 15)    3           3 LOAD_FAST                1 (d)               6 LOAD_FAST                0 (key)               9 BINARY_SUBSCR              10 RETURN_VALUE              11 POP_BLOCK              12 JUMP_FORWARD            23 (to 38)    4     >>   15 DUP_TOP              16 LOAD_GLOBAL              0 (KeyError)              19 COMPARE_OP              10 (exception match)              22 JUMP_IF_FALSE           11 (to 36)              25 POP_TOP              26 POP_TOP              27 POP_TOP              28 POP_TOP    5          29 LOAD_CONST               1 ('default')              32 RETURN_VALUE              33 JUMP_FORWARD             2 (to 38)         >>   36 POP_TOP              37 END_FINALLY         >>   38 LOAD_CONST               0 (None)              41 RETURN_VALUE 
like image 25
Aleksa Avatar answered Oct 19 '22 16:10

Aleksa


Last time I checked, the first one is a few nanoseconds faster. But most phythonistas seem to favor the second one.

I think I'm not the only one that want to reserve exceptions for exceptional behavior, so I try to use the first one, reserving the second one when it's invalid not to have the key

like image 43
Javier Avatar answered Oct 19 '22 18:10

Javier