2

One of my function will use external variables, but the external variables will change when I use this function. Here is an example:

func_list=[]
for i in range(0,6):
    def func():
        print(i)
    func_list.append(func)
for j in range(0,6):
    func_list[j]()

I hope the output is [1,2,3,4,5,6], but the real output is [6,6,6,6,6,6] I know one of solution is using closure, like this:

func_list=[]
for i in range(0,6):
    def create_func():
        nonlocal i
        number=i
        def func():
            print(number)
        return func
    func=create_func()
    func_list.append(func)
for j in range(0,6):
    func_list[j]()

This programs could output [1,2,3,4,5,6]. But it looks a bit ugly. It use additional 4, at least 3, lines to solve this problem...Is there some more simple methods/function decorations to solve this problem?

thank you.

X. Li
  • 23
  • 2

1 Answers1

0

Try this:

func_list=[]
for i in range(0,6):
    def func(i = i):
        print(i)
    func_list.append(func)

for j in range(0,6):
    func_list[j]()

It works because i is evaluated in the function definition and its value is put in as the default for the keyword argument, not the variable.

Of course, if you need to pass in a keyword argument called i, this will break down, in which case you probably want to use the (uglier) solution you gave.

anonymoose
  • 819
  • 2
  • 11
  • 25
  • Thank you, that's what I want. Maybe it is the best solution. – X. Li Apr 19 '17 at 22:56
  • @X.Li You could try [this much better answer](http://stackoverflow.com/questions/3431676/creating-functions-in-a-loop#3431699). I found shortly it after answering this. – anonymoose Apr 19 '17 at 23:07
  • Thank you, I have seen that. That could be a good answer. But your answer is good enough for me. – X. Li Apr 22 '17 at 13:10
  • @X.Li You can accept answers that worked for you by clicking the check mark below the vote buttons. – anonymoose May 06 '17 at 18:59
  • sorry for forgot accept answer. I have done just now. Thank you again. – X. Li Jun 14 '17 at 21:52