简体   繁体   中英

Python: for statement 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

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

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

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

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.

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:

替代文字

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:
链接文字

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

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM