Well I believe the first lines are obvious:
foods = {}
name = "potato"
The important thing to remember here is that dicts are mutuable objects.
Next, what we have is a dict assignment:
foods[name] = x
As described in How can I add new keys to a dictionary?, this basically says: "Associate the value x
to the key name
inside foods
". If name
already exists in foods
with some value, that value will be overridden with x
. If it does not exist in the dict, a new key:value
pair will be created.
This will NEVER raise an error*, because we don't assume anything about the keys - it is not necessary. As explained above, if the key doesn't exist a new pair will be created. If the key exists already, it will be updated. Internally, the dict's __setitem__
method is called to allow this behaviour: foods[name] = x --> foods.__setitem__(name, x)
.
The value in this case is:
foods.get(name, 0) + 1
As described in Why dict.get(key) instead of dict[key]?, The get
method is used if we don't want the code to fail if some keys are missing. It has an optional argument default
(which its default is None
). This means that dict.get(key, default)
works the same as dict[key]
as long as the key exists in the dict! If it doesn't exist already, then default
will be returned instead.
So this line can be read as "add 1 to the value of name
from foods
if it exists in the dict, else just return 1 (0 + 1
)". This is a common construct for implementing some counter. We can use this single line to replace the following cumbersome structure:
if name in foods:
foods[name] += 1
else:
foods[name] = 1
You can now see the direct replacement: If the key exists, get
will return its value, then we add 1 and save it back to the dict - equivalent to foods[name] += 1
. If it doesn't exist in the dict, get
will return 0
, then we add 1 to get 1, and save that in the dict - equivalent to foods[name] = 1
.
Another alternative is to use a defaultdict
with int type:
foods = defaultdict(int)
foods[name] += 1
This encapsulates all that logic and when a key doesn't exist in the dict and we try to access it, the type we provided is called to create a default value. In this case, int()
returns 0
as desired.
* For hashable keys.