Reputation: 17322
I'm trying to figure out what is the reason for having None
as the default value for dict.get
but no default value (without specifying the default value) for dict.pop
{}.get('my_key')
# output: None
{}.pop('my_key')
# output: KeyError: 'my_key'
I was thinking that the reason for not having implicit default value for dict.pop
is because you may have keys with value None
so, in order to not get confused if your key is in the dictionary or not, an implicit default value for dict.pop
doesn't make so much sense. But then again this explanation should be valid also for dict.get
and isn't:
{'my_key': None}.get('my_key')
# output: None
# but doesn't tell you if the key is truly in the dictionary or not
Upvotes: 9
Views: 4067
Reputation: 21
This is what i believe:
pop() main purpose: value+deletion get() main purpose: value
if the 'value' part fails, your program can deal with it, None might even be fine to continue with. Maybe you just wanted to test if a key was there. Using get() is actually named as a solution to check-if-value-is-present-in-dict questions.
if 'deletion' fails you usually didn't test-delete, but actually wanted to delete and made some e.g. indexing mistake. So if that did not work, you should be informed.
so you might say "this behaviour is the result of the definition, not the explanation", yes and the explanation i think, is, that the same behaviour was present in other programming languages (C) before and it made sense to implement it into python. It might lay even deeper though.
FredrikHedman's response:
In short a good example of the "principle of least surprise" and the Zen of Python (import this) :)
this also makes sense for me
Upvotes: 0
Reputation: 1253
My take on this is to allow a dict
to be used with different
contexts.
With dict.get(key)
we always get a value even if the key is not
present in dict
. The default value can be provided. No exception is raised.
The dict
is not changed.
With dict.pop(key)
we get a value only when the key
is present in
dict
, otherwise an exception is raised. We may avoid the exception
by providing a default value. The dict
is changed.
To test for the presence of key
we use key in dict
.
For dict.pop
, this gives a similar interface to what list.pop
,
set.pop
and deque.pop
provides.
In short a good example of the "principle of least surprise" and the Zen of Python (import this) :)
Upvotes: 2
Reputation: 98
Here an example to show you what is basically going on under the hood, if the key exists, also showing the difference between both:
In [3]: foo = {'my_key': 'value', 'other_key': 'other_val'}
In [4]: foo.get('my_key')
Out[4]: 'value'
In [5]: bar = foo.pop('other_key')
In [6]: bar
Out[6]: 'other_val'
In [7]: foo
Out[7]: {'my_key': 'value'}
In [8]:
Upvotes: 0
Reputation: 634
The method which read the exact value for key is
{}['my_key']
The dict.get(key[, default]) is the try get value, if not return "default" version.
help(dict.get)
get(...)
D.get(k[,d]) -> D[k] if k in D, else d. d defaults to None.
Upvotes: 3
Reputation: 13888
If your primary concern is if a key exists within the dictionary, it should be done via 'my_key' in my_dict
. .get
and .pop
as you can imagine serves slightly different purposes. .get
is strictly retrieval, and .pop
is retrieval and removal. You will want to use the respective method that best suit your use case, and employ a default value if you don't need to handle a KeyError
.
As for the reason of why .pop
doesn't use a default value by default, it is because that the operation expects to also remove a key from the dictionary. If the operation was completed successfully without raising an error, one might erroneously expect the key to be removed from the dictionary as well.
For .get
, the method exists specifically as a alternative to provide a default value over the __getitem__
method, which you usually see the syntax as my_dict['my_key']
. The latter of which, will raise a KeyError
if the key doesn't exist.
Upvotes: 7
Reputation: 531993
get
exists, in some sense, in two varieties: one raises a KeyError
, the other doesn't.
>>> {}['my_key']
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
KeyError: 'my_key'
>>> {}.get('my_key')
>>>
pop
, on the other hand, isn't an error-free version of another operation that raises a KeyError
, so it's used in both situations: raising a KeyError
by default, but returning a default value if requested.
>>> {}.pop('my_key')
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
KeyError: 'my_key'
>>> {}.pop('my_key', 3)
3
Upvotes: 5