Почему разделенные запятыми итерации в for не работают как zip? - PullRequest
0 голосов
/ 10 декабря 2018

Я хочу понять, почему следующий код

for x, y in [1,2], [3,4]:
    print(x, y, x + y)

печатает

1 2 3
3 4 7

вместо

1 3 4
2 4 6

Теперь я знаю, что zip делаетэту работу и , не использующую zip для итерации по паре списков, можно считать анти-паттерном , но мне все еще нужно объяснение этого поведения по умолчанию.

С моей точки зрения,приведенный выше код должен интуитивно работать так же, как встроенная функция zip

for (x, y) in zip([1,2], [3,4]):
    print(x, y, x + y)

, которая печатает

1 3 4
2 4 6

Из памяти я помню, как видел объяснение этой техники давным-давно (и я думаю,вот почему это решение приходит на ум в первую очередь), но сейчас я провел поиск, в том числе по всему разделу 5 документации по Python 3, но я не смог найти никаких объяснений такого поведения, даже в раздел 5.6.(Looping Techniques) .

Это 4-й Gotcha ?

Ответы [ 3 ]

0 голосов
/ 10 декабря 2018

Посмотрите на это:

>>> [1,2],[3,4]
([1, 2], [3, 4])
>>> list(zip([1,2],[3,4]))
[(1, 3), (2, 4)]
>>> 

Результаты отличаются, поэтому, когда вы повторяете как:

for x,y in [1,2],[3,4]:
    ...

это будет примерно так:

x=1
y=2
# next loop
x=3
y=4

И когда цикл имеет вид:

for x,y in zip([1,2],[3,4]):
    ...

Он повторяется как:

x=1
y=3
# next loop
x=2
y=4

Вот почему Python создал метод zip.

0 голосов
/ 10 декабря 2018

Интуитивно понятный способ понять первое поведение - это думать о

for x, y in [1,2], [3,4]:

как о разложении

for z in [[1,2],[3,4]]:

, где

z[0] = [1,2]
z[1] = [3,4]
0 голосов
/ 10 декабря 2018

Я думаю, что это ожидаемое поведение!
Учтите, что [1,2], [3,4] - это литерал кортежа, эквивалентный кортежу ([1,2], [3,4]).(Вы можете использовать это, даже не замечая этого, например, при назначении нескольких значений с помощью a, b, c = 10, 20, 30 без учета () ...).

Итак, в вашем примере цикл повторяет этот список следующим образом:

# First iteration we get:
x, y = [1, 2]  
# Which is the same as:
x = 1
y = 2
# Which would print:
print(x, y, x+y)
>> 1, 2, 3

# Second iteration we get:
x, y = [3, 4]  
# Which is the same as:
x = 3
y = 4
# Which would print:
print(x, y, x+y)
>> 3, 4, 7  

Имеет ли это смысл сейчас?


Учитывая zip: If zipбудет делать то же самое, тогда Я бы с подозрением!Как это очень распространенное и полезное, но совершенно излишнее дело?Разве никто не заметил ?Так что вы не должны ожидать, что они сделают то же самое!;-)


Редактировать из-за запроса указателя на документацию.
От 5.3 Кортежи и последовательности :

Кортеж состоитиз числа значений, разделенных запятыми, например: ...
Как видите, на выходе кортежи всегда заключаются в круглые скобки, поэтому вложенные кортежи интерпретируются правильно;они могут быть введены с или без окружающих скобок, хотя часто все равно необходимы скобки (если кортеж является частью большего выражения).

...