right now my lambda function is :
In [40]: f=lambda x, count=0: count if not(x%3==0) else count+1
In [41]: [f(x) for x in range(10)]
Out[41]: [1, 0, 0, 1, 0, 0, 1, 0, 0, 1]
But what I really want is to accumulate the count, so that the output would be:
Out[42]: [1, 1, 1, 2, 2, 2, 3, 3, 3, 4]
I am looking for some code like:
f=lambda x, count=0: nonlocal count if not(x%3==0) else count+1
but got a syntax error message for the use of "nonlocal". So my question is: is there a way to define nonlocal variable in lambda?
In general, lambda functions should be pure functions, that is why they are purposefully restricted to expressions.
As such, you cannot assign to a nonlocal/global variable in a lambda expression (although, you can use assignment expressions to assign to local variables).
If you want to use nonlocal
/global
and assign to a variable, you can always just use a function definition statement. You never have to use a lambda expression to create a function. And lambda expressions are purposefully restricted in their capabilities. If you want something beyond that, just use a function definition statement.
But in this case, you shouldn't do that In this case, you are trying to use a list-comprehension for side-effects. This is generally confusing and considered an anti-pattern. It is better to simply use a for-loop:
result = []
count = 0
for i in range(10):
if i%3 == 0:
count += 1
result.append(count)
This is perfectly pythonic.
But if you wanted a more functional programming approach, you should use itertools.accumulate
:
import itertools
result = itertools.accumulate(map(lambda x: int(x%3 == 0), range(10)))
Lambda expression cannot contain statements like nonlocal
or global
. But you should choose the right tool for the job, and in this case, it is either just a normal for-loop, or itertools.accumualte
.