使用随机python的奇怪输出
我有一个问题,我根据随机性对列表进行排序。该算法的工作原理是选择一个介于0到N-1(N是列表的长度)之间的随机数,并使用迭代索引交换 我有两种不同的算法使用随机python的奇怪输出,python,variables,random,Python,Variables,Random,我有一个问题,我根据随机性对列表进行排序。该算法的工作原理是选择一个介于0到N-1(N是列表的长度)之间的随机数,并使用迭代索引交换 我有两种不同的算法 import random def algo1(xx): for i in xrange(len(xx)): p = random.randrange(i, len(xx)) # random number between i and len(xx) - 1 xx[i], xx[p] = xx[p],
import random
def algo1(xx):
for i in xrange(len(xx)):
p = random.randrange(i, len(xx)) # random number between i and len(xx) - 1
xx[i], xx[p] = xx[p], xx[i]
return xx
def algo2(yy):
for i in xrange(len(yy)):
p = random.randrange(0, len(yy)) # random number between 0 and len(xx) - 1
yy[i], yy[p] = yy[p], yy[i]
return yy
k = range(5)
print algo1(k)
print algo2(k)
这里一切正常。我打印来自algo1和algo2的返回值
但是当我将返回值存储在变量中时
z1 = algo1(k)
z2 = algo2(k)
print z1
print z2
它们都包含相同的列表。我运行了多少次,它们显示相同的返回值
查看此视频您正在修改列表(我假设您使用的是python 2.7)。因此,当您使用
algo2
洗牌k
时,也会影响z1
。这三个列表实际上是同一个对象。您需要创建一个列表副本,例如algo1(k[:])
我还要看一看,它能做你想做的事情。请注意,
random.shuffle
也会就地修改输入,因此您也需要[:]
。您正在就地修改列表(我假设您使用的是python 2.7)。因此,当您使用algo2
洗牌k
时,也会影响z1
。这三个列表实际上是同一个对象。您需要创建一个列表副本,例如algo1(k[:])
我还要看一看,它能做你想做的事情。请注意,
random.shuffle
也会就地修改输入,因此您也需要[:]
。您的函数会更改k
并返回对它的引用。没有创建新的列表
你所看到的不同之处在于:
- 当您打印时,您将显示
返回的内容的当前状态(这是对algoX
的引用)k
- 当分配结果时,将
和z1
设置为z2
的引用,意思是k
。并且您仅在完成操作z1是z2是k
之后打印。这就是为什么你会看到相同的结果,所有这3个变量都对同一个列表有相同的引用k
k
并返回对它的引用。没有创建新的列表
你所看到的不同之处在于:
- 当您打印时,您将显示
返回的内容的当前状态(这是对algoX
的引用)k
- 当分配结果时,将
和z1
设置为z2
的引用,意思是k
。并且您仅在完成操作z1是z2是k
之后打印。这就是为什么你会看到相同的结果,所有这3个变量都对同一个列表有相同的引用k
k
时,您每次都在修改相同的数据
尝试使用:
print("z1", id(z1))
print("z2", id(z2))
print("k", id(k))
这将返回变量的标识。您会注意到z1、z2和k都具有相同的标识
在第一种情况下,在调用下一个函数之前直接打印输出。这就是为什么你没有注意到这种行为
但是,当您分配返回变量、保存它然后打印它时,您会注意到这个问题
若要解决此问题,请在函数内部创建一个新列表,为其赋值并返回该列表,而不是修改已传递到函数中的列表。在向两个函数传递、修改和返回相同的变量(list)
k
时,每次修改的数据相同
尝试使用:
print("z1", id(z1))
print("z2", id(z2))
print("k", id(k))
这将返回变量的标识。您会注意到z1、z2和k都具有相同的标识
在第一种情况下,在调用下一个函数之前直接打印输出。这就是为什么你没有注意到这种行为
但是,当您分配返回变量、保存它然后打印它时,您会注意到这个问题
若要解决此问题,请在函数内部创建一个新列表,为其赋值并返回该列表,而不是修改已传递到函数中的列表。尝试以下操作:
z1 = algo1(k)
print z1
z2 = algo2(k)
print z2
print z1
print k
您只需覆盖相同的列表。谷歌搜索“python不可变与可变类型”以了解这种行为。试试以下方法:
z1 = algo1(k)
print z1
z2 = algo2(k)
print z2
print z1
print k
您只需覆盖相同的列表。谷歌搜索“python不可变类型vs可变类型”来理解这种行为。我不明白将范围(5)传递给函数时您在做什么。for循环的范围长度(5)仅为5,因此您的循环可能是“for i in xrange(5):`在调用之间移动打印z1,它会再次工作。。。不严重,
assert id(z1)==id(z2)
将显示,这些名称指向相同的列表,因此只保留最后的修改。更改函数或将其包装在列表构造函数中,如:z1=list(algo1(k))
或制作切片副本,如z1=algo1(k)[:]
-这些方法都应该修复原因或症状;-)我不明白你把范围(5)传递给你的函数时在做什么。for循环的范围长度(5)仅为5,因此您的循环可能是“for i in xrange(5):`在调用之间移动打印z1,它会再次工作。。。不严重,assert id(z1)==id(z2)
将显示,这些名称指向相同的列表,因此只保留最后的修改。更改函数或将其包装在列表构造函数中,如:z1=list(algo1(k))
或制作切片副本,如z1=algo1(k)[:]
-这些方法都应该修复原因或症状;-)