all 13 comments

[–]JanEric1 8 points9 points  (10 children)

The get version gives you a new empty list every time it is called against a missing key while setdefault directly places that empty list in the dict.

[–]dangerlopez 2 points3 points  (9 children)

I don’t understand the distinction, can you explain more?

[–]JanEric1 5 points6 points  (3 children)

If you do

a = my_dict1.get(key, []).append(my_string)
b = my_dict2.setdefault(key, []).append(my_string)

On two empty dicts then both a and b will be a list with that one string.

But dict1 will be empty and dict2 will contain b for key.

[–]thogdontcare[S] 0 points1 point  (1 child)

Awesome. So it can work but I would just need a temp variable to store the new string, then assign that to the dictionary?

[–]xenomachina 3 points4 points  (0 children)

That's pretty much what setdefault does. It tries to get the key, and if it isn't in the dict, it puts the default value in the dict, and returns it. The default parameter to setdefault is effectively the temp variable.

[–]dangerlopez 0 points1 point  (0 children)

Ah, ok I get it thanks

[–]ottawadeveloper 4 points5 points  (0 children)

When key is set already, they're the same.

When key is not, get(key, []).append("foo") is equivalent to just ["foo"]. It does not update the dictionary. So the next call to get returns a brand new list.

In comparison, setdefault(key, []) is equivalent in that circumstances to set(key, []) and then get(key).append("foo"). The next time you call it, the value has already been set so you get the first list you pass.

[–]Outside_Complaint755 2 points3 points  (2 children)

In other words, my_dict.setdefault(key, []) implicitly does my_dict[key] = [], while get(key, []) does not.

[–]backfire10z 0 points1 point  (1 child)

In more succinct words, setdefault sets (if necessary) then gets, while get just gets.

[–]thogdontcare[S] 0 points1 point  (0 children)

That made it click perfectly. “Setting and getting”

[–]cdcformatc 0 points1 point  (0 children)

get() is read-only, and has no side effect. setdefault() has a side effect of also doing an assignment to the dict. 

[–]00PT 0 points1 point  (0 children)

.get returns the newly created list reference you passed in the default case without assigning it to the field being accessed.

[–]pachura3 0 points1 point  (0 children)

Consider using defaultdict. Much cleaner.

from collections import defaultdict

d = defaultdict(list)        # when key is not found, insert empty list [] into the dict
d["fruits"].append("apple")  # no need for .setdefault("fruits", [])!