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