Python list of nested lambdas executes last element of lambda list only

Viewed 54

The following code snippet demonstrates that a list of nested lambdas evaluates to the last element of the original list of lambdas only.

eqs_test = [
    (lambda x: f"0"),
    (lambda x: f"1"),
    (lambda x: f"2"),
    (lambda x: f"3"),
]

# unexpected output
print([a(1) for a in [
    lambda x: f"{e1(0)}-{e2(0)}" for e1, e2 in zip(eqs_test[1:], eqs_test[:-1])
]])

# expected output (no outer lambda used here for testing)
print([a for a in [
    f"{e1(0)}-{e2(0)}" for e1, e2 in zip(eqs_test[1:], eqs_test[:-1])
]])

The output is:

['3-2', '3-2', '3-2']
['1-0', '2-1', '3-2']

I would expect the second output in both cases but somehow the lambda is not stored properly (3-2 is only the last generated lambda). What is happening here and how can I store the outer lambda in such a way that it runs the correct nested lambda?

1 Answers

To make the first example work, store the variables as lambda parameters. Otherwise, the lambda will print last values of e1 and e2 always:

eqs_test = [
    (lambda x: f"0"),
    (lambda x: f"1"),
    (lambda x: f"2"),
    (lambda x: f"3"),
]

# unexpected output
print([a(1) for a in [
    lambda x, e1=e1, e2=e2: f"{e1(0)}-{e2(0)}" for e1, e2 in zip(eqs_test[1:], eqs_test[:-1])
]])

Prints:

['1-0', '2-1', '3-2']
Related