I have met a strange Python behavior which is difficult to explain to myself. When I pass a default value for getting a key from a dict - looks like it firstly try to find that default value and next looks if key exists. And throws an error if the key exists in the dict. Why does that happen?
from collections import namedtuple
Test = namedtuple("TEST", "attr1 attr2 attr3")
obj_1 = Test("first", "second", "third")
obj_1.attr1
>>> 'first'
k_dict = {"red": "light", "green": "leaf"}
k_dict.get("red")
>>> 'light'
k_dict.get("red", obj_1.attr4)
Traceback (most recent call last):
File "<input>", line 1, in <module>
AttributeError: 'TEST' object has no attribute 'attr4'
UPDATE: I understand what is the problem here, but I can't understand why this is default behaviur of Python? Why not just check first part - if the key is in the dict and if not - check another part? Now it looks like not optimal way of computing that?
it has nothing to do with dict.get
When you call a function in python, arguments are evaluated.
In your case the key exists, but both arguments need to be evaluated before key lookup occurs.
For instance what would "work" would be:
k_dict.get("red") or obj_1.attr4
Since red key exists, the second argument isn't evaluated. It only crashes if red doesn't exist. It doesn't help much in that case (your way of doing it has the merit to catch the error whatever the outcome is at least so keep on doing it!), but if you had some complex computation to perform as the default argument it would:
k_dict.get("red",super_expensive_computation())
is slow even if red exists when:
k_dict.get("red") or super_expensive_computation()
is fast when red exists. The or technique relies on the fact that the values cannot be 0, just None. Else just use if "red" in k_dict construct.
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