在使用list.append(a), 添加动态改变的a(a = random.random())时,发现循环中每个新的循环改变的a会在list中把以前的值所有改变;app
查找后自了,Python是基于对象引用的,append添加的是一个“地址、引用”,当这个地址内的内容改变时,前面的同“地址”的内容都改变。dom
查看“内存、应用”’使用 id(object).测试
简单的就不啰嗦了网上关于地址内存都有介绍,通过测试后发现,通常状况下给变量 一个新值时这个id就会改变,固然这个值如果和之前spa
相同这个id就同样。在for循环中这个状况就不同code
import random def test(): return random.random() def test1(): for i in range(3): for i in range(2): a = test() print('a_id=',id(a))
结果是对象
a_id= 2566513744848 a_id= 2566513744872 a_id= 2566513744848 a_id= 2566513744872 a_id= 2566513744848 a_id= 2566513744872
能够看到内存分配时,对应内层2次循环的给了2个2个地址,节省开支; 若是是这样的话使用list.append()最后就只有6个元素2个结果,blog
可是内存
import random list_a = [] list = [1,2,3,4,5,6] def test(): return random.random() def test1(): for i in range(3): for i in range(2): a = test() print('a_id=',id(a)) list_a.append(a) print(list_a) test1()
结果io
a_id= 2566513744824 a_id= 2566513744848 a_id= 2566513744968 a_id= 2566513744992 a_id= 2566513745016 a_id= 2566513745040 [0.5481244502902065, 0.7452961787111314, 0.6038274060224955, 0.8269310521431017, 0.4091898711994284, 0.45233748625853376]
能够看到地址都改变了,Python在运行时又分配的新的地址、引用,因此前面的数值没有变化。for循环
说了怎么多尚未到问题的重点;
import random list_a = [] list = [[1,1,0,1,0], [1,0,1,1,1]] def mutation(array): array.append(random.randint(1,10)) return array def test2(): for num in list: for i in range(3): a = mutation(num) print(a) print('a_id=',id(a)) list_a.append(a) print(list_a) test2()
[1, 1, 0, 1, 0, 8] a_id= 2566513576904 [1, 1, 0, 1, 0, 8, 10] a_id= 2566513576904 [1, 1, 0, 1, 0, 8, 10, 3] a_id= 2566513576904 [1, 0, 1, 1, 1, 3] a_id= 2566515364744 [1, 0, 1, 1, 1, 3, 5] a_id= 2566515364744 [1, 0, 1, 1, 1, 3, 5, 4] a_id= 2566515364744 [[1, 1, 0, 1, 0, 8, 10, 3], [1, 1, 0, 1, 0, 8, 10, 3], [1, 1, 0, 1, 0, 8, 10, 3], [1, 0, 1, 1, 1, 3, 5, 4], [1, 0, 1, 1, 1, 3, 5, 4], [1, 0, 1, 1, 1, 3, 5, 4]]
结果能够看到我向list中添加了一个新的值,但在list中元素的改变并不会改变list的id,内层3个循环中list的id始终不变,
在加到list_a中的内层的3个循环中,始终是一个id,外层第一个循环结束后,取了此id的最后一个值,因此最后list_a的前3个值都相同。
实际上网上一个list里加字典例子和这个道理是同样的,双层循环的内存循环了不改变id的对象,
只是我写的时候把list变成其余形式了如([sum(list),,,]),找缘由时也就看了id和转换的结果发现好多结果都同样,
被其余的好多猜错试的好多,找了很久才发现缘由。
解决这个问题的办法是用copy,在
mutation(array) 中copy要return的array产生一个新的id,(array = copy.copy(array)),至因而用浅拷贝仍是深拷贝就要看array的维度。