Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

`if key in dict` vs. `try/except` - which is more readable idiom?

I have a question about idioms and readability, and there seems to be a clash of Python philosophies for this particular case:

I want to build dictionary A from dictionary B. If a specific key does not exist in B, then do nothing and continue on.

Which way is better?

try:     A["blah"] = B["blah"] except KeyError:     pass 

or

if "blah" in B:     A["blah"] = B["blah"] 

"Do and ask for forgiveness" vs. "simplicity and explicitness".

Which is better and why?

like image 897
LeeMobile Avatar asked Dec 22 '10 18:12

LeeMobile


People also ask

What happens if you attempt to pop a key from a dictionary and the key does not exist?

What happens if you attempt to pop a key from a dictionary and the key does not exist, and you specified no default return? An error will be raised.

What happens if you try to access a value in the dictionary using a key that does not exist Python?

If given key does not exists in dictionary, then it returns the passed default value argument. If given key does not exists in dictionary and Default value is also not provided, then it returns None.

How do you test if a key is in a dictionary?

Using has_key() method returns true if a given key is available in the dictionary, otherwise, it returns a false. With the Inbuilt method has_key(), use the if statement to check if the key is present in the dictionary or not.

What special method is called when you try to access a dictionary key that doesn't exist?

3. KeyError is what's thrown when you access a key that doesn't exist in the dictionary.


2 Answers

Exceptions are not conditionals.

The conditional version is clearer. That's natural: this is straightforward flow control, which is what conditionals are designed for, not exceptions.

The exception version is primarily used as an optimization when doing these lookups in a loop: for some algorithms it allows eliminating tests from inner loops. It doesn't have that benefit here. It has the small advantage that it avoids having to say "blah" twice, but if you're doing a lot of these you should probably have a helper move_key function anyway.

In general, I'd strongly recommend sticking with the conditional version by default unless you have a specific reason not to. Conditionals are the obvious way to do this, which is usually a strong recommendation to prefer one solution over another.

like image 145
Glenn Maynard Avatar answered Sep 24 '22 22:09

Glenn Maynard


There is also a third way that avoids both exceptions and double-lookup, which can be important if the lookup is expensive:

value = B.get("blah", None) if value is not None:      A["blah"] = value 

In case you expect the dictionary to contain None values, you can use some more esoteric constants like NotImplemented, Ellipsis or make a new one:

MyConst = object() def update_key(A, B, key):     value = B.get(key, MyConst)     if value is not MyConst:          A[key] = value 

Anyway, using update() is the most readable option for me:

a.update((k, b[k]) for k in ("foo", "bar", "blah") if k in b) 
like image 42
lqc Avatar answered Sep 26 '22 22:09

lqc