tags:

views:

95

answers:

4

Hi all.

My question concerns the output of this statement:

for x in range(4), y in range(4):
    print x
    print y

Results in:

[0, 1, 2, 3]
2
True
2

It seems there is a comparison involved, I just can't figure out why the output is structured like this.

+3  A: 

You've created a weird, weird thing there.

>>> y = 2
>>> range(4), y in range(4)
([0, 1, 2, 3], True)

The y in range(4) is a membership test.

The range(4), y in range(4) is a pair of items; a tuple.

The variable x is set to range(4), then the result of y in range(4).

The variable y is just laying around with a value; it is not set by the for statement.

This only works hacking around on the command line typing random stuff with y left laying around.

This isn't sensible Python code at all.

[And yes, the word in has two meanings. So do ()'s and several other pieces of syntax.]

S.Lott
It wasn't supposed to be used in any script I was just wondering what happens here
BandGap
+3  A: 

You seem to have y defined prior to running this code. What you're iterating over is a two-item tuple: first item is range-generated list, second is True, which is result of the y in range(4):

>>> y = 2
>>> for x in range(4), y in range(4):
    print x, 'x'
    print y, 'y'


[0, 1, 2, 3] x
2 y
True x
2 y

What I suspect you were trying to do is to iterate over two variables from two lists. Use zip for this.

SilentGhost
Ok seems I initialised the y some lines up. I didn't notice that
BandGap
+1 Nice demonstration.
Skurmedel
@BandGap: then you'd get a `NameError: name 'y' is not defined`. So I'm pretty sure it is initialised.
SilentGhost
@BandGap, how about testing that with another print prior to running the loop?
Unreason
+6  A: 

My guess is that you're running this from an interactive console, and already had y defined with a value of 2 (otherwise, you'd get NameError: name 'y' is not defined). That would lead to the output you observed.

This is due to for x in range(4), y in range(4): actually being equivalent to the following when evaluated:

for x in (range(4), y in range(4)):

which reduces to...

for x in ([0,1,2,3], 2 in range(4)):

which again reduces to...

for x in ([0,1,2,3], True):

This then results in 2 iterations of the for loop, since it iterates over each element of the tuple:

  1. x = [0,1,2,3]
  2. x = True.

(And of course, y is still 2.)

Amber
Thanks for this in depth analysis
BandGap
+1  A: 

Dav nailed down perfectly why the syntax you wrote doesn't work. Here are the syntaxes that do work for what you're probably trying to do:


If you want all 4 x 4 combinations for x and y, you want 2 nested loops:

for x in range(4):
    for y in range(4):
        print x, y

Or if you really want to use one loop:

import itertools
for (x, y) in itertools.product(range(4), range(4)):
    print x, y

itertools.product() generates all possible combinations:

alt text

This is less readable than 2 loops in this simple case, but the itertools module has many other powerful functions and is worth knowing...


If you want x and y to advance in parallel over two sequences (aka "lock-step" iteration):

for (x, y) in zip(range(4), range(4)):
    print x, y
# `zip(range(4), range(4))` is silly since you get x == y;
# would be useful for different sequences, e.g.
# zip(range(4), 'abcd')

[Background: The name zip comes from Haskell; think about how a Zipper takes one tooth from here and one from there:
link text

zip() cuts off to the length of the shortest sequence; the itertools module has other variants...]

Beni Cherniavsky-Paskin
`zip(range(4), range(4))` is rather useless example ;)
SilentGhost
I know how zip works. Thanks. I'm not a total noob just because SilentGhost tagged the question 'beginner'
BandGap
BandGap: How would we know? I think this is a good answer, he obviously took his time to help.
Skurmedel
Sorry, didn't mean to sound condescending, just believe that self-contained explanations are better on average. Also, people that might google the question *would* be python noobs in some cases. [And put the pictures in becase I really like the zipper animation; I now dream of building some animated programming reference...]
Beni Cherniavsky-Paskin