I was trying to solve this little challenge:
You want a defaultdict that uses a different value every time a non-existent key is looked up, i.e. a counter; 1 for the first non-existent key, 2 for the second, etc.
I was able to solve it like:
from collections import defaultdict
def f(a=[0]):
a[0]+=1
return a[0]
s=defaultdict(f)
The bonus was to try to do this in one line.
s=defaultdict(lambda a=[0]: (a[0]+=1))
SyntaxError: invalid syntax _________^
Is there a way to do this in a lambda? Update the mutable default arg and return?
There are two problems:
... += ... is a statement, not an expression. You could call __iadd__ explicitly, except ...int doesn't define __iadd__; a[0] += 1 is just implemented as a[0] = a[0] + 1.What you need to do is call __setitem__ explicitly to update the 0th element of the default list value. That returns None, not a[0], so you'll also need an or expression to return the value of a[0] (since None or x == x):
>>> s = defaultdict(lambda a=[0]: a.__setitem__(0, a[0] + 1) or a[0])
>>> s[6]
1
>>> s[9]
2
>>> s[6]
1
>>> s[8]
3
(I'd write defaultdict(itertools.count(0).__next__) myself.)
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