On Sunday, March 27, 2016 at 9:55:16 AM UTC-4, g vim wrote: > Given that Python, like Ruby, is an object-oriented language
It turns out that "object-oriented" means very little, and lots of languages that are object-oriented will behave differently from each other, even where object behavior is concerned. > why doesn't > this: > > def m(): > a = [] > for i in range(3): a.append(lambda: i) > return a > > b = m() > for n in range(3): print(b[n]()) # => 2 2 2 > > ... work the same as this in Ruby: > > def m > a = [] > (0..2).each {|i| a << ->(){i}} > a > end > > aa = m > (0..2).each {|n| puts aa[n].()} # => 0 1 2 > Like Jussi, I don't know Ruby enough to tell you why Ruby *does* work as you want, but I can help explain why Python doesn't work as you want. When you write "lambda: i", you are creating a closure, because i is a name from outside the lambda. In that case, the function you create with the lambda refers to the variable i, not to the value i had when you made the lambda. Later, when you run the function, it will use the current value of the variable i. In this case, you have three functions, all of which refer to the same i, and when you run them all, i is 2, so they all produce 2. > > lambda i=i: i > > ... is needed to make it work in Python. Just wondered why? Here you are using the local i as the default value for the function parameter i. Function parameter defaults are evaluated when the function is defined, and the value is stored as part of the function. So all three of your functions store a different value as the default for i. When the functions are called, they each use their distinct value as the default for the missing argument, and they produce 0, 1, 2. --Ned. -- https://mail.python.org/mailman/listinfo/python-list