Brian Quinlan wrote:
This is from Python built from the py3k branch: >>> c = (lambda : i for i in range(11, 16)) >>> for q in c: ... print(q()) ... 11 12 13 14 15 >>> # This is expected >>> c = (lambda : i for i in range(11, 16)) >>> d = list(c) >>> for q in d: ... print(q()) ... 15 15 15 15 15 >>> # I was very surprised
You are entitled to be surprised. Then figure out what is going on. Hint: it is the moral equivalent of what is happening here: >>> c = [] >>> for i in range(11, 16): c.append(lambda: i) >>> i = 'Surprise!' >>> print([f() for f in c]) ['Surprise!', 'Surprise!', 'Surprise!', 'Surprise!', 'Surprise!'] >>> i = 0 >>> print([f() for f in c]) [0, 0, 0, 0, 0] The body of your lambda is an un-evaluated expression with a reference, not an expression evaluated at the time of loading c. TO get what you expected, try this: >>> c = [] >>> for i in range(11, 16): c.append(lambda i=i: i) >>> i = 'Surprise!' >>> print([f() for f in c]) [11, 12, 13, 14, 15] When you evaluate a lambda expression, the default args are evaluated, but the expression inside the lambda body is not. When you apply that evaluated lambda expression, the expression inside the lambda body is is evaluated and returned. --Scott David Daniels scott.dani...@acm.org -- http://mail.python.org/mailman/listinfo/python-list