Python: for instruction behavior

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

      

There seems to be a comparison, I just can't figure out why the output is structured like this.

+2


a source to share


4 answers


I am assuming you are running this from the interactive console and have already defined y

with a value of 2 (otherwise you will get NameError: name 'y' is not defined

). This will lead to what you notice.

This is because it is for x in range(4), y in range(4):

actually equivalent to the following when evaluated:

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

      

which boils down to ...

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

      



which again boils down to ...

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

      

This then results in two iterations of the loop for

as it iterates over each element of the tuple:

  • x = [0,1,2,3]

  • x = True

    ...

(And of course y

it doesn't care 2.)

+6


a source


You have created a strange, strange thing.

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

      

y in range(4)

is a membership test.

range(4), y in range(4)

- a couple of elements; tuple.

The variable is x

set to range (4) and then the result y in range(4)

.



The variable y

just fits with the value; it is not specified by the operator for

.

This only works on the command line, typing random things from the y

left.

This is not sane Python code at all.

[And yes, the word in

has two meanings. So there are a ()

few other syntaxes.]

+3


a source


It seems like before running this code you have y

. What you are range

iterating over is a two-way tuple: the first item is the generated list, the second is True

which is the result 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 are trying to do is loop over two variables from two lists. Use zip

for this.

+3


a source


Been nailed long ago as to why the syntax you wrote doesn't work. Here are the syntaxes that work for what you are 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 a single loop:

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

      

itertools.product()

generates all possible combinations:

alt text

It's less readable than 2 loops in this simple case, but the itertools module has many other powerful features and is worth knowing ...


If you want to x

, and y

advancing in parallel on two sequences (aka iteration of "lock-step"):

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 lightning takes one tooth from here and one from there:
link text

zip()

cut to the length of the shortest sequence; the itertools module has other options ...]

+1


a source







All Articles