Python: для поведения заявления - PullRequest
2 голосов
/ 05 мая 2010

Мой вопрос касается вывода этого утверждения:

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

Результат:

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

Похоже, что это связано с сравнением, я просто не могу понять, почему выходные данные так структурированы.

Ответы [ 4 ]

6 голосов
/ 05 мая 2010

Я предполагаю, что вы запускаете это с интерактивной консоли, и для y уже задано значение 2 (в противном случае вы получите NameError: name 'y' is not defined). Это приведет к полученному вами результату.

Это связано с тем, что for x in range(4), y in range(4): фактически эквивалентно следующему при оценке:

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

, который уменьшается до ...

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

, который снова сводится к ...

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

Это приводит к двум итерациям цикла for, поскольку он повторяется по каждому элементу кортежа:

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

(И, конечно, y - это еще 2.)

3 голосов
/ 05 мая 2010

Вы, похоже, определили y до запуска этого кода. То, что вы перебираете, - это кортеж из двух элементов: первый элемент - это список range, второй - True, который является результатом 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

Я подозреваю, что вы пытались сделать, это перебрать две переменные из двух списков. Для этого используйте zip.

3 голосов
/ 05 мая 2010

Вы создали странную, странную вещь там.

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

y in range(4) - членский тест.

range(4), y in range(4) - это пара предметов; кортеж.

Переменная x устанавливается в диапазон (4), затем результат y in range(4).

Переменная y просто лежит со значением; он не устанавливается оператором for.

Это работает только для взлома командной строки, когда вы набираете случайные вещи, а y оставляете без дела.

Это совсем не разумный код Python.

[И да, слово in имеет два значения. Так же поступают () и некоторые другие части синтаксиса.]

1 голос
/ 05 мая 2010

Дав отлично понял, почему написанный вами синтаксис не работает. Вот синтаксис, который работает для того, что вы, вероятно, пытаетесь сделать:


Если вы хотите все 4 x 4 комбинации для x и y, вам нужно 2 вложенных цикла:

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

Или, если вы действительно хотите использовать один цикл:

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

itertools.product() генерирует все возможные комбинации:

alt text

Это менее читабельно, чем 2 цикла в этом простом случае, но модуль itertools имеет много других мощных функций и его стоит знать ...


Если вы хотите, чтобы x и y продвигались параллельно по двум последовательностям (или итерация "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')

[Фон: имя zip происходит от Хаскелла; подумайте о том, как молния берет один зуб отсюда и один оттуда:
link text

zip() обрезается до длины самой короткой последовательности; у модуля itertools есть другие варианты ...]

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...