假设我想创建一个带数字序列的嵌套列表,我不想重复列表序列。
即。我想要这样的事情:[[1,2,3,4],[2,1,3,4],[4,2,3,1]]
,其中列表的len
取决于我可以在有限的尝试中生成多少非重复的数字序列(在下面的情况下四次尝试)
所以这是我的第一次尝试:
import random
rng = random.Random()
bd =list(range(4))
i = 0
result =[]
while i <4:
rng.shuffle(bd)
if bd not in result:
result.append(bd)
i +=1
print(result)
我在进入while循环之前先创建了一个列表bd = [0,1,2,3]
。
在运行上面的代码时,每次我的嵌套列表中只有一个元素令人惊讶。
结果:[[1, 2, 0, 3]]
但是,如果我稍微修改一下代码,它就像我预期的那样工作。 这是我修改过的代码:
import random
rng = random.Random()
i = 0
result =[]
while i <4:
bd =list(range(4))
rng.shuffle(bd)
if bd not in result:
result.append(bd)
i +=1
print(result)
结果:[[3, 2, 0, 1], [1, 0, 3, 2], [0, 1, 3, 2]]
我所做的只是重新调整每个循环中的列表bd
。
根据我的理解,列表bd
将在每个循环中进行随机播放,因此将bd
重置为[0,1,2,3]
应该毫无意义。
有人可以向我解释为什么修改后的代码有效吗?谢谢。
答案 0 :(得分:2)
Python中的列表和类似对象引用引用。请考虑以下简单示例:
a_list = [1,2,3,4,5]
another_list = []
for i in range(5):
another_list.append(a_list)
a_list[0] = i + 10
print(another_list)
您希望输出为:
[[10, 2, 3, 4, 5], [11, 2, 3, 4, 5], [12, 2, 3, 4, 5], [13, 2, 3, 4, 5], [14, 2, 3, 4, 5]]
但是,您看到的输出是:
[[14, 2, 3, 4, 5], [14, 2, 3, 4, 5], [14, 2, 3, 4, 5], [14, 2, 3, 4, 5], [14, 2, 3, 4, 5]]
每次拨打another_list.append(a_list)
时,都会将引用附加到a_list
。然后,您更改a_list
,之前附加的引用指向更改的列表。
最后,a_list
等于[14, 2, 3, 4, 5]
,another_list
包含对此列表的五个相同引用。
回到你的案子。为防止这种情况发生,您可以在每次追加时创建列表副本as documented here:
import random
rng = random.Random()
i = 0
result =[]
while i <4:
bd =list(range(4))
rng.shuffle(bd)
if bd not in result:
# Use [:] to create a slice of bd which actually contains the whole list
result.append(bd[:])
i +=1
print(result)
答案 1 :(得分:1)
在您第一次尝试时,您每次都会随机播放并附加相同的列表。尝试使用整个列表中的一个副本来使用副本:bd[:]
是一个完全独立的对象,当您下次循环循环原始bd
时,它不会被更改。
import random
rng = random.Random()
bd =list(range(4))
i = 0
result =[]
while i <4:
rng.shuffle(bd)
if bd not in result:
result.append(bd[:])
i +=1
print(result)
输出:
[[2, 1, 3, 0], [1, 2, 3, 0], [0, 3, 2, 1]]
答案 2 :(得分:1)
这种情况发生的原因是您将bd
追加到result
,并且在下一次使用bd
的迭代中,它们具有相同的参考。
在第二个中,您将在每次迭代中生成一个新列表(不同的引用)。
答案 3 :(得分:1)
你的代码有点麻烦:shuffle执行就地更改,因此它会更改变量引用的对象。通过运行第一个代码,您将始终获得一个结果 - 最后一个洗牌操作。为了避免这种情况,你应该附上一份清单:
PDO