list-display semantics?

Bengt Richter bokr at accessone.com
Sun Jun 10 23:54:27 CEST 2001


On Mon, 11 Jun 2001 02:29:47 +0800, "jainweiwu" <parywu at seed.net.tw>
wrote:

>Hi all:
>I tried the one-line command in a interaction mode:
>[x for x in [1, 2, 3], y for y in [4, 5, 6]]
>and the result surprised me, that is:
>[[1,2,3],[1,2,3],[1,2,3],9,9,9]
>Who can explain the behavior?
>Since I expected the result should be:
>[[1,4],[1,5],[1,6],[2,4],...]
>--
>Pary All Rough Yet.
>parywu at seed.net.tw
>
>

I think the first comma made your expression legal
and equivalent to

	[x for x in ([1, 2, 3], y) for y in [4, 5, 6]]

so x took on two values: [1, 2, 3] and the incoming value
of y, which happened to be bound to a left-over 9 from
some previous activity, because the bindings for the elements
of the sequence ([1, 2, 3], y) were set up before the y loop
got started. So the loop y sequenced 4-5-6 for for three elements
of [1, 2, 3] and then x took on the value of y from the tuple
which hadn't changed it was created, hence the 9, for three more
elements of the final result. The actual values for the y loop
make no difference except that the last will be available next
time. Do a del y and you will get a NameError exception if you
try to re-run your statement.

Since you used y for the for expression, if you ran the
expression again, you'd get 6's in the place of the 9's.

 >>> y='y' 
 >>> [x for x in [1, 2, 3], y for y in [4, 5, 6]]
 [[1, 2, 3], [1, 2, 3], [1, 2, 3], 'y', 'y', 'y']
 >>> [x for x in [1, 2, 3], y for y in [4, 5, 6]]
 [[1, 2, 3], [1, 2, 3], [1, 2, 3], 6, 6, 6]

Then note the 6 left over from the first go above.

Try the following (with [4,5,6]) to get what you expected.
(I left off the 6 to avoid line wrap here :)

 >>> [[x,y] for x in[1,2,3] for y in [4,5]]
 [[1, 4], [1, 5], [2, 4], [2, 5], [3, 4], [3, 5]]

(caveat lector: I am neither Latinist nor Python guru
yet ;-)




More information about the Python-list mailing list