3 ms·
> I've always thought there's a much simpler language struggling to get out of Python I agree, although I suspect we have different ideas as to which parts of
by bakery2k 8y ago
> I've always thought there's a much simpler language struggling to get out of Python
I agree, although I suspect we have different ideas as to which parts of Python would be included in that simpler language. For example, I quite like the consistency of "everything-is-an-object".
FWIW some of the Python core developers have started to express a similar sentiment. Especially in the last few versions, where Python has got much more complex with the addition of type annotations and multiple `async/await` features. I wonder whether the retirement of the BDFL will slow down Python's rate of growth, or accelerate it?
> nested generator comprehensions behave differently than nested list conprehensions
I haven't come across this - could you give an example?
- colanderman 8y agoSure: >>> [[x*y for y in xrange(1,5)] for x in xrange(1,5)] [[1, 2, 3, 4], [2, 4, 6, 8], [3, 6, 9, 12], [4, 8, 12, 16]] >>> list([x*y for y in xrange(1,5)] for x in xrange(1,5)) [[1, 2, 3, 4], [2, 4, 6, 8], [3, 6, 9, 12], [4, 8, 12, 16]] >>> [list(l) for l in ((x*y for y in xrange(1,5)) for x in xrange(1,5))] [[1, 2, 3, 4], [2, 4, 6, 8], [3, 6, 9, 12], [4, 8, 12, 16]] >>> [list(l) for l in [(x*y for y in xrange(1,5)) for x in xrange(1,5)]] [[4, 8, 12, 16], [4, 8, 12, 16], [4, 8, 12, 16], [4, 8, 12, 16]] The problem is that the `x` in the inner comprehension gets somehow linked to the variable `x` in the outer comprehension, rather that the value of `x`. (This matches Python's similarly bizarre closure semantics.) So, the results are "as expected" when either (a) the inner comprehension is evaluated eagerly (first and second example), or (b) the outer comprehension is evaluated lazily (second and third examples). But if both the inner and outer comprehensions are evaluated lazily, the inner comprehensions just see whatever the "last" value of `x` was, which I think to many people is surprising. (No less so than mutable default arguments, at least.)
- bakery2k 8y agoYou're right, this is the same problem that Python has with closures, for example: >>> l = [] >>> for i in range(10): ... l.append(lambda: i) ... >>> for j in range(10): ... print(l[j](), end=' ') ... 9 9 9 9 9 9 9 9 9 9 The issue isn't really closing over the variable instead of the value, but the fact that Python re-uses the same variable for each iteration of the loop. C# used to behave the same way, but its designers considered this bad enough that they made a breaking change to the language to fix it [1]. Unfortunately, C#'s solution (creating a new variable for each execution of the loop body) isn't really an option for Python. It would conflict with the rest of the language, which only uses variables scoped to whole functions. Note that Go makes the same mistake as in earlier versions of C# [2]. [1] https://ericlippert.com/2009/11/12/closing-over-the-loop-variable-considered-harmful-part-one/ https://ericlippert.com/2009/11/12/closing-over-the-loop-var... [2] https://play.golang.org/p/Pt6BN2Mj-WL https://play.golang.org/p/Pt6BN2Mj-WL