0

I'm not sure what to call this issue exactly, but I believe it's best if I just show a simple example of what I'm trying to do.

import matplotlib.pyplot as plt
import numpy as np

func_list = []
for i in range(1, 4):
    func_list.append(lambda x: x*i)  # This is just the function of a line with some slope "i"

d = np.linspace(0, 5)

for func in func_list:
    plt.plot(d, func(d))

plt.grid()
plt.show()

I want this snippet to plot three different lines with different slops. Right now, it is plotting three lines with the same slope, and I know why. The value of i (which is 3; the last iteration in the first for loop) is the same each time I call func.

When I am appending the function to the list func_list, how can I force it to use the value of i at the time I am appending it to the list? I believe there is a solution using the memory address of i instead, but even if I changed the function creation line to this: func_list.append(lambda x: x*ctypes.cast(id(i), ctyptes.py_object).value), it wouldn't change a thing because it would still be using the same id.

Gabe Morris
  • 804
  • 4
  • 21
  • No. Don't even think about memory addresses, Python is a high level, object oriented language. – juanpa.arrivillaga Oct 17 '21 at 23:11
  • Do you have another approach in mind? @juanpa.arrivillaga – Gabe Morris Oct 17 '21 at 23:12
  • 1
    Python uses lexical scoping. `i` is a free variable, closed over the `i` created by the for-loop statement. The "correct" way is to use *another* function scope to capture the variable, so something like `def func_maker(i): return lambda x: x*i` then in your loop use `func_list.append(func_maker(i))` – juanpa.arrivillaga Oct 17 '21 at 23:17
  • 1
    Alternatively, although this is kinda hacky, it is a common idiom, you can exploit default values, so you could use `func_list.append(lambda x, i=i: return x*i)`, of course, that changes the signature – juanpa.arrivillaga Oct 17 '21 at 23:18
  • 1
    This is what I was looking for. Thank you! I didn't know what to call this which gave me a hard time finding an answer. @juanpa.arrivillaga – Gabe Morris Oct 17 '21 at 23:22

0 Answers0