为什么 for 中的逗号分隔迭代不像 zip 那样工作?
Why comma separated iterables in for doesn't work like zip?
我想明白的是为什么下面的代码
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 可以完成这项工作 not using zip to iterate over a pair of lists could be considered an anti-pattern,但我仍然需要对此默认行为的解释。
从我的角度来看,上面的代码应该像内置的 zip 函数一样直观地工作
for (x, y) in zip([1,2], [3,4]):
print(x, y, x + y)
打印
1 3 4
2 4 6
凭记忆我记得很久以前看到过这个技术的解释(我想这就是为什么首先想到这个解决方案的原因),但我现在已经进行了搜索,包括 [=] 的整个第 5 节34=] 3 文档,但我找不到对此行为的任何解释,甚至在 section 5.6. (Looping Techniques).
上也找不到
这是第 4 个 Gotcha 吗?
我认为这是预期的行为!
考虑 [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:如果 zip 会做同样的事情,那么我会怀疑!怎么会有这种非常常见且被认为有用但完全多余的东西?没有人注意到吗?所以你不应该期望他们也这样做! ;-)
根据对文档指针的请求进行编辑。
来自 5.3 Tuples and Sequences:
A tuple consists of a number of values separated by commas, for
instance: ...
As you see, on output tuples are always enclosed in
parentheses, so that nested tuples are interpreted correctly; they may
be input with or without surrounding parentheses, although often
parentheses are necessary anyway (if the tuple is part of a larger
expression).
看看这个:
>>> [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
方法的原因。
理解第一个行为的直观方法是思考
for x, y in [1,2], [3,4]:
作为
的分解
for z in [[1,2],[3,4]]:
哪里
z[0] = [1,2]
z[1] = [3,4]
我想明白的是为什么下面的代码
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 可以完成这项工作 not using zip to iterate over a pair of lists could be considered an anti-pattern,但我仍然需要对此默认行为的解释。
从我的角度来看,上面的代码应该像内置的 zip 函数一样直观地工作
for (x, y) in zip([1,2], [3,4]):
print(x, y, x + y)
打印
1 3 4
2 4 6
凭记忆我记得很久以前看到过这个技术的解释(我想这就是为什么首先想到这个解决方案的原因),但我现在已经进行了搜索,包括 [=] 的整个第 5 节34=] 3 文档,但我找不到对此行为的任何解释,甚至在 section 5.6. (Looping Techniques).
上也找不到这是第 4 个 Gotcha 吗?
我认为这是预期的行为!
考虑 [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:如果 zip 会做同样的事情,那么我会怀疑!怎么会有这种非常常见且被认为有用但完全多余的东西?没有人注意到吗?所以你不应该期望他们也这样做! ;-)
根据对文档指针的请求进行编辑。
来自 5.3 Tuples and Sequences:
A tuple consists of a number of values separated by commas, for instance: ...
As you see, on output tuples are always enclosed in parentheses, so that nested tuples are interpreted correctly; they may be input with or without surrounding parentheses, although often parentheses are necessary anyway (if the tuple is part of a larger expression).
看看这个:
>>> [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
方法的原因。
理解第一个行为的直观方法是思考
for x, y in [1,2], [3,4]:
作为
的分解for z in [[1,2],[3,4]]:
哪里
z[0] = [1,2]
z[1] = [3,4]