因此,我一直在编写一些非常随机的实验代码,结果令我感到困惑。
这是我的代码
from random import choice
class A:
def __init__(self, l):
parsed = iter(l)
self.include = next(parsed) == "+"
self.l = list(parsed)
def get(self, l):
rt = self.l
if self.include:
rt += l
return choice(rt)
a = A("+abcd")
d = dict()
for key in "abcdef":
d[key] = 0
for i in range(100000):
d[a.get(["e", "f"])] += 1
print(d)
Run Code Online (Sandbox Code Playgroud)
我希望代码能输出随机但有些均匀的选择分布。像这样:
{'a': 16678, 'b': 16539, 'c': 16759, 'd': 16584, 'e': 16631, 'f': 16809}
Run Code Online (Sandbox Code Playgroud)
但是实际输出是这样的:
{'a': 3, 'b': 4, 'c': 7, 'd': 3, 'e': 49588, 'f': 50395}
Run Code Online (Sandbox Code Playgroud)
我的意思是,这是随机的,但是如果那是真实的话,那么到现在我可能还已经中了10次彩票。
那么,这到底是怎么回事?为什么random.choice功能更愿意选择"e"和"f"这么多比其他人呢?
random.choice很好 您只是没有从自己认为的选项中进行选择。在get:
rt = self.l
if self.include:
rt += l
Run Code Online (Sandbox Code Playgroud)
您没有复制self.l。每个rt += l对象都附加到同一个列表对象,因此该列表最终以一个'e'g和一个s和'f's 结束,并且大多数情况下都会被选中。
为避免这种情况,您可以预先复制self.l:
rt = self.l[:]
if self.include:
rt += l
Run Code Online (Sandbox Code Playgroud)
或者,您可以使用+代替+=,因为它+可以建立一个新列表,而不是改变左侧:
rt = self.l
if self.include:
rt = rt + l
Run Code Online (Sandbox Code Playgroud)