2

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.

4
  • 2
    Is this the actual code? Mine fails on the for with NameError: name 'y' is not defined. Which version of Python are you using? Commented May 5, 2010 at 10:20
  • Are you trying to write nested loops? What tutorial are you using? Commented May 5, 2010 at 10:23
  • @Marcelo: y was initialised earlier as I failed to notice. See answers below. @S.Lott: No tutorial. Just noticed this while trying to find a short form for a loop over two variables... Commented May 5, 2010 at 10:28
  • Perhaps you should find a good tutorial. Commented May 5, 2010 at 14:09

4 Answers 4

6

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.)

Sign up to request clarification or add additional context in comments.

1 Comment

Thanks for this in depth analysis
3

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.]

1 Comment

It wasn't supposed to be used in any script I was just wondering what happens here
3

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.

3 Comments

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

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...]

4 Comments

zip(range(4), range(4)) is rather useless example ;)
I know how zip works. Thanks. I'm not a total noob just because SilentGhost tagged the question 'beginner'
BandGap: How would we know? I think this is a good answer, he obviously took his time to help.
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...]

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.