5 ms·
I very recently learned about dict().setdefault() For instance: def myfunc(**kwargs): # we need to be sure kwargs has ['foo'] set, with 'bar' as the def
by MPSimmons 5y ago
I very recently learned about dict().setdefault()
For instance:
def myfunc(**kwargs):
# we need to be sure kwargs has ['foo'] set, with 'bar' as the default:
kwargs['foo'] = kwargs.get('foo', 'bar')
We could write that this way:
def myfunc(**kwargs):
kwargs.setdefault('foo', 'bar')
- wodenokoto 5y agoFor this particular use case, shouldn’t you just set the default value in the function definition or am I missing something? Def myfunc(foo=“Bar”): pass
- amelius 5y agoYou can't use this if you also have a nonlocal or global variable named foo that you want to access. foo = 123 def myfunc(foo="bar"): global foo # problem!
- diarrhea 5y agoThe main 'problem' there is the `global` keyword :^) (it's not needed for read access)
- amelius 5y agoHow would you read foo if it is hidden by a local parameter.
- diarrhea 5y agoI guess not at all. It's shadowed. But this being Python, this is a way: foo = 123 def lol(foo="bar"): print(globals()["foo"], foo) That will output "123 bar". But it's terrible! Your example is a SyntaxError, it doesn't even compile: In [1]: def myfunc(foo="bar"): ...: global foo Input In [1] global foo ^ SyntaxError: name 'foo' is parameter and global
- amelius 5y ago> But this being Python, this is a way That's why I said nonlocal or global ;)
- oneoff786 5y agoSeems like you shouldn’t do that?
- MPSimmons 5y agoThat would make the local variable foo in myfunc equal to "bar", as opposed to setting a key named foo in the dictionary kwargs equal to "bar". edit Nevermind, I see what you mean. Yes, it would be equivalent, but it can be used in other scenarios. This was just the one I thought of.
- alduin32 5y agoA good example scenario for setdefault/defaultdict is grouping a list of tuples : grouped = {} for (key, value) in ungrouped: group = new.setdefault(key, []) group.append(value) defaultdict(list) would make it even shorter, but setdefault() is more general, as it makes it possible to have a "default" value that depends on the key itself. defaultdict combined with late-binding closures also allows to define nested dictionaries : nested_dict = lambda: defaultdict(nested) nested = nested_dict() nested[0][1][2] = "value"
- RussianCow 5y agoIt’s convenient when you need to pass the entire kwargs dict to something else, but still need to ensure that one or two values have defaults if they aren’t set.
- cycomanic 5y agoThank you! I have had to use the clutch of your first example many times and never knew about dict.setdefaults.
- JoBrad 5y agoWhy not just use defaultdict?
- VWWHFSfQ 5y agobecause you may not have been the one that created the dict
- aahortwwy 5y agosetdefault also returns the value: is_foo_enabled = config.setdefault('foo', False)