这样输出两边会多0,是为什么,我的0不应该是在输出以后加的吗
Topic source主要原因在于insert和append的原理上。insert和append在添加的时候不会改变列表的内存地址,而+方法会同时改变列表的内存地址(也就是说实际上换了一个列表)。
在某一次循环正常输出后(假设输出[1,1]吧),存到result里后,进入下一次循环——关键点来了:由于insert和append不会改变列表内存地址,因此在这次循环中,虽然你预想中会创造一个新L“[0,1,1,0]”用于计算,但是,由于存在result里的L地址不变,所以事实上是改了前一个已经存好的L“[1,1]”为“[0,1,1,0]”。因为输出并不是在yield以后立即输出的,而是整体弄完后再输出的,所以最后会变成[0,1,1,0]而非[0,0]。
至于为什么两边不会有多个0,那是因为,在之后运行+方法(也就是那个L = L[i]+L[i+1]...)的时候,L的地址变了,再用insert和append不会再影响最初的[0,1,1,0]了。
最终结果就变成了:你每执行一次循环,就会给上一次循环得出的那个列表两边多加两个0。
所以你会发现无论杨辉三角是几层,最后都会有一样的结果:总是最后一个两边没有0。
如果把insert和append改为L = [0] + L + [0],问题就解决了。
根本来说,主要原因在于python保存变量的原理上,python的变量默认存的是地址而不是值,所以有”在python中没有赋值,只有引用“一说。
如果挑一个类似的简单例子的话:直接赋值产生新列表,如果你改变新列表,原列表的值也会变。
@INDifferenceeeee
整体弄完是指下面的部分,不是在说triangles()。你说的执行到yield 就停没有问题,问题是函数本身的设计和下面的部分不太匹配:
n = 0
results = []
for t in triangles():
results.append(t)
n = n + 1
if n == 10:
break
for t in results:
print(t)
for t in triangles()部分仅执行append循环,并没有print。是执行完所有append后才print。
也就是说是先保存、再修改(保存的部分),再保存、再修改......依次循环下去,到最后才输出。
但是,如果把print直接放到上面的while部分内,代替掉yield,就不会出现两边有[0]的情形了,因为是先输出后修改的(尽管这样就不是生成器了)。
- 1
轻涉世
def triangles2():
L = [1]
yield L
while True:
L.insert(0, 0)
L.append(0)
L = [L[i] + L[i+1] for i in range(len(L) - 1)]
L = L
yield L