当我试图从集合中选择一个伪随机元素时,我看到了非确定性行为,即使RNG是种子(下面显示的示例代码)。为什么会发生这种情况,我是否应该期望其他Python数据类型显示类似的行为?在
注意:我只在Python2.7上测试过这个,但它在两台不同的Windows计算机上都是可复制的。在
相似问题:Python random seed not working with Genetic Programming example code处的问题可能类似。根据我的测试,我的假设是,集合中运行到运行的内存分配差异导致不同的元素为同一RNG状态选取。在
到目前为止,我还没有在Python文档中找到任何关于set或random的警告/问题。在
示例代码(randTest生成不同的输出运行):
import random
''' Class contains a large set of pseudo-random numbers. '''
class bigSet:
def __init__(self):
self.a = set()
for n in range(2000):
self.a.add(random.random())
return
''' Main test function. '''
def randTest():
''' Seed the PRNG. '''
random.seed(0)
''' Create sets of bigSet elements, presumably many memory allocations. '''
b = set()
for n in range (2000):
b.add(bigSet())
''' Pick a random value from a random bigSet. Would have expected this to be deterministic. '''
c = random.sample(b,1)[0]
print('randVal: ' + str(random.random())) #This value is always the same
print('setSample: ' + str(random.sample(c.a,1)[0])) #This value can change run-to-run
return
我很确定您是正确的,这个问题是由
set
的运行间内存分配差异引起的。当我将程序更改为使用列表而不是集合时,我得到了确定性行为:它与可变对象的对象实例化有关。如果我创建一个
set
的frozenset
,它确实会给出一个确定的结果如果我没搞错的话,CPython使用(可变)对象的内存位置作为它的id和散列键。在
因此,虽然对象的内容总是相同的,但它的id将不同
^{pr2}$一个可能的解决方案是将一个冻结集的子类化。在
相关问题 更多 >
编程相关推荐