Velocity Reviews > Bug in list comprehensions?

Bug in list comprehensions?

Iain King
Guest
Posts: n/a

 06-07-2006
I was playing with list comprehensions, to try and work out how doubled
up versions work (like this one from another thread: [i for i in
range(9) for j in range(i)]). I think I've figured that out, but I
found something strange along the way:

>>> alpha = ["one", "two", "three"]
>>> beta = ["A", "B", "C"]
>>> [x for x in alpha for y in beta]

['one', 'one', 'one', 'two', 'two', 'two', 'three', 'three', 'three']
>>> [x for x in y for y in beta]

['C', 'C', 'C']
>>> beta = [alpha, alpha, alpha]
>>> beta

[['one', 'two', 'three'], ['one', 'two', 'three'], ['one', 'two',
'three']]
>>> [x for x in y for y in beta]

['C', 'C', 'C']
>>> [y for y in beta]

[['one', 'two', 'three'], ['one', 'two', 'three'], ['one', 'two',
'three']]
>>> [x for x in y for y in beta]

['one', 'one', 'one', 'two', 'two', 'two', 'three', 'three', 'three']

Shoudn't both lines '[x for x in y for y in beta]' produce the same
list?
I'm guessing I'm the one confused here... but I'm confused! What's
going on?

Iain

Fredrik Lundh
Guest
Posts: n/a

 06-07-2006
Iain King wrote:

> I'm guessing I'm the one confused here... but I'm confused! What's
> going on?

reading the documentation may help:

/.../ the elements of the new list are those that would be produced
by considering each of the for or if clauses a block, nesting from left
to right, and evaluating the expression to produce a list element each
time the innermost block is reached.

the clauses nest from left to right, not from right to left, so "[x for
x in y for y in beta]" is equivalent to

out = []
for x in y:
for y in beta:
out.append(x)

</F>

Duncan Booth
Guest
Posts: n/a

 06-07-2006
Iain King wrote:

>>>> [x for x in y for y in beta]

> ['C', 'C', 'C']
>>>> [y for y in beta]

> [['one', 'two', 'three'], ['one', 'two', 'three'], ['one', 'two',
> 'three']]
>>>> [x for x in y for y in beta]

> ['one', 'one', 'one', 'two', 'two', 'two', 'three', 'three', 'three']
>
> Shoudn't both lines '[x for x in y for y in beta]' produce the same
> list?

[x for x in y for y in beta] is a shorthand for:

tmp = []
for x in y:
for y in beta:
tmp.append(x)

So x iterates over whatever y is before the loop starts, and y iterates
over beta (but that doesn't affect what x is iterating over).

The important thing is to remember that the order of 'for' and 'if'
statements is the same as though you had written the for loop out in full.

Sion Arrowsmith
Guest
Posts: n/a

 06-07-2006
Fredrik Lundh <(E-Mail Removed)> wrote:
>Iain King wrote:
>> I'm guessing I'm the one confused here... but I'm confused! What's
>> going on?

>the clauses nest from left to right, not from right to left, so "[x for
>x in y for y in beta]" is equivalent to
>
> out = []
> for x in y:
> for y in beta:
> out.append(x)

And a list comprehension doesn't get a namespace to itself (cf.
generator comprehensions) so "leaks" its variables. Exactly as
above. So the y being iterated over in "for x in y" is the y
from the previous inner iteration ("for y in beta").

--
\S -- http://www.velocityreviews.com/forums/(E-Mail Removed) -- http://www.chaos.org.uk/~sion/
___ | "Frankly I have no feelings towards penguins one way or the other"
\X/ | -- Arthur C. Clarke
her nu becomež se bera eadward ofdun hlęddre heafdes bęce bump bump bump

 Thread Tools

 Posting Rules You may not post new threads You may not post replies You may not post attachments You may not edit your posts BB code is On Smilies are On [IMG] code is On HTML code is OffTrackbacks are On Pingbacks are On Refbacks are Off Forum Rules

 Similar Threads Thread Thread Starter Forum Replies Last Post iwasjoeking HTML 9 06-09-2008 11:43 PM Debajit Adhikary Python 17 10-18-2007 06:45 PM David Raleigh Arnold Firefox 12 04-02-2007 03:13 AM dackz Python 0 02-06-2007 04:44 PM roopa C++ 6 08-27-2004 06:18 PM

Advertisments