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?
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.
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.
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.
3. KeyError is what's thrown when you access a key that doesn't exist in the dictionary.
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.
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)
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With