Python中for循环与直接赋值输出结果不一致,[12,13,14,15]和[20,21,22,23]为何不同?
def add(a, b):
return a + b
def test():
for r_i in range(4):
yield r_i
g = test()
#0 1 2 3
# g = (add(2, i) for i in g)
# g = (add(10, i) for i in g)
# print(list(g))
#[12, 13, 14, 15]
for n in [2, 10]:
# 0 1 2 3
# 2 1 2 3
g = (add(n, i) for i in g)
#第一次循环 n=2,i 第一次循环 0 相加结果 2 3 4 5
#第二次循环 n=10,i 第一次循环 2 相加结果 12 13 14 15
print(list(g))
#为啥输出[20, 21, 22, 23]
Python中for循环与直接赋值输出结果不一致,[12,13,14,15]和[20,21,22,23]为何不同?
打印 add 的参数 a 和 b,可以发现 a 在循环的方式中始终是 10,也就是 n 引用的始终是最后一次循环 n 的值,这和直接传值的方式是不一样的。
我无法理解你的问题。
#1 如果用列表生成式就不会出现这种情况,因为生成器只有在被遍历时才会进行运算。
#2 列表生成式则会一次性进行所有的运算
换成列表生产式 g = [add(n, i) for i in g],for 和单独传值结果一致[12, 13, 14, 15],不明白是怎么推算出[20, 21, 22, 23],for 第二次循环会覆盖上次循环的值吧。
感觉是 python 语言的糟粕。。
如果遍历一次生成器表达式,那么 g 就没值了,生成器表达式 g = (add(n, i) for i in g) for i in g 不会遍历 g 么
#6 g 在第一次遍历时没值了,但是你又赋值给 g 了。。。
逐级遍历吧
比如一开始 g 是 0 1 2 3,第一次循环 的第一次遍历
2 1 2 3
2 3 2 3
2 3 4 3
2 3 4 5
这样理解对么
n 一直是 10 哇,结果应该是 10+10+i
10+10+i 是怎么来的呢
#8 不懂你在讲哪个方面了。。。
在循环的方式下,第一次循环时,g 的值为
(
add(2, 0),
add(2, 1),
add(2, 2),
add(2, 3)
)
第二次循环时,g 的值为
(
add(10, add(10, 0)),
add(10, add(10, 1)),
add(10, add(10, 2)),
add(10, add(10, 3))
)
原来如此,明白了,感谢
我记得叫 late binding 机制吧,两次计算的时候 n=10
你把 2 改成 None 或者字符串,你就发现问题了
g = (add(n, i) for i in g) 改成 g = [add(n, i) for i in g] 就达到要求了
a = [1, 2]
a[1] = a
print(a[1])
补门一个问题
为啥结果是:
[1, […]]
因为 a[1]是 a 自己啊
所以会无限循环下去
你会发现 a[1], a[1][1], a[1][1][1]… 都是[1, […]]
#16
#13 说的准确一些,因为 lambda 表达式放在列表生成式也会出现这种现象,具体的讲解可以搜索关键词 late binding


