4 ms·
The "consuming generator" problem is a good point, but their workaround misses a better solution. In Python 3, range() returns a range object, which has a __con
by zwegner 13y ago
The "consuming generator" problem is a good point, but their workaround misses a better solution. In Python 3, range() returns a range object, which has a __contains__ method, so you can use "in" just fine without consuming any generators. It's also much faster (it would be constant time/memory except for the fact that integers can have arbitrary size).
l = range(5)
print('2 in l,', 2 in l)
print('3 in l,', 3 in l)
print('1 in l,', 1 in l)
prints...
2 in l, True
3 in l, True
1 in l, True
Also, the lambda/closure example is something that really irritates me about Python. Both dynamic and lexical scoping have this problem: they always reevaluate the variable inside the closure whenever it's called, the only difference is which parent scope the value is pulled from (the parent scope or the calling scope). It's not that the "last lambda is being reused", as the article says, but rather, there are five different lambdas, but they each refer to the same variable, which is set to 4 after the list comprehension. This sucks for metaprogramming, where you'd like to create a bunch of copies of a function with different parameterizations. There's two workarounds that I know of for this for dynamic scoping: creating another nested scope, or using keyword arguments. I'm not sure what you'd do for lexical scoping (but who uses that anyways?).
for x in [(lambda i: lambda: i)(i) for i in range(5)]:
print(x())
...or...
for x in [lambda i=i: i for i in range(5)]:
print(x())
In my purely-functional Python-like programming language, Mutagen, closures are static, so that they capture the value of variables from the enclosing scope at the point that they're defined. So this works as you'd expect, printing 0 and 1 (no list comprehensions yet, and lambdas are full functions, and of course lists are immutable so no +=):
lambdas = []
for x in [0, 1]:
lambdas = lambdas + [lambda: return x;]
for l in lambdas:
print(l())