3

Say I want to get a list of functions that returns x * 0, x * 1, ..., x * 9 (x is the input variable). I am using a lambda expression in a list comprehension. Below is my code with x = 1:

x = 1
funcs = [lambda x: x * i for i in range(10)]
res = [f(x) for f in funcs]
print(res)

However, I am getting

[9, 9, 9, 9, 9, 9, 9, 9, 9, 9]

The expected result should be

[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

What is wrong with my code and how should I fix it?

Shaun Han
  • 2,676
  • 2
  • 9
  • 29
  • 1
    following the linked duplicate post: `funcs = [lambda x, i=i: x * i for i in range(10)]`. – Tom Jun 26 '21 at 17:09
  • `lambda x: x * i` has a free variable, `i`. When you *call the function*, `i` is equal to `9`, the last value it was assigned to in the list comprehension. – juanpa.arrivillaga Jun 26 '21 at 18:01
  • 1
    The "principled" way of doing this is to create a factory function, e.g. `def makefunc(i): return lambda x: x*i` then in your comprehension, `[makefunc(i) for i in range(10)]` – juanpa.arrivillaga Jun 26 '21 at 18:02
  • Just for completeness, the `lamba x, i=i:` technique is called "capturing" the current value of i. – Tim Roberts Jun 26 '21 at 18:04

0 Answers0