当前位置: 首页 > 面试题库 >

Set.pop()不是随机的吗?

毋举
2023-03-14
问题内容

在python文档中,“
set.pop()从s中删除并返回任意元素”。在生成一些随机数据以测试程序时,我注意到此pop()函数的异常行为。这是我的代码(python 2.7.3):

testCases = 10
numberRange = 500

poppedValues = []
greaterPercentages = []

for i in range (testCases):
    s = Set()

    """ inserting 100 random values in the set, in the range [0, numberRange) """
    for j in range (100):
        s.add(random.randrange(numberRange))

    poppedValue = s.pop()
    greaterCount = 0

    """ counting how many numbers in the set are smaller then the popped value """
    for number in s:
        if poppedValue > number:
            greaterCount += 1

    poppedValues.append(poppedValue)
    greaterPercentages.append(float(greaterCount) / len(s) * 100)

for poppedValue in poppedValues:
    print poppedValue, '\t',

print

for percentage in greaterPercentages:
    print "{:2.2f}".format(percentage), '\t',

我在这里做的是

  1. s在每个元素的范围为[0,numberRange)的集合中插入一些随机值
  2. 从集合中弹出一个元素(根据文档,它应该是随机的)
  3. 计算集合中有多少元素小于弹出值

我希望弹出的值应该是随机数,并且集合中大约50%的数字会大于弹出的值。但似乎pop()几乎总是返回集合中的最低数字。这是的结果numberRange = 500。第一行表示弹出元素的值。第二行是小于弹出值的元素所占的百分比。

9   0   3   1   409     0   1   2   4   0   
0 % 0 % 0 % 0 % 87 %    0 % 0 % 0 % 0 % 0 %

我使用的不同值进行了此测试numberRange。似乎对于set元素的较低值,pop()几乎总是返回最低的元素。但是对于更高的值,它将返回一个随机元素。对于numberRange = 1000,结果为:

518     3586    3594    4103    2560    3087    4095    3079    3076    1622    
7 %     72 %    73 %    84 %    54 %    51 %    79 %    63 %    67 %    32 %

我认为这是非常随机的。为什么会有这种奇怪的行为?难道我做错了什么?

编辑 :感谢大家的回答和评论,似乎通过“任意”,不能保证它将是“随机的”。


问题答案:

这是一个实现细节-set被实现为HashMap(类似于dict但没有用于值的插槽),set.pop删除HashMap中的第一个条目,并且ints哈希值与int相同。

结合起来,这意味着您的set,实际上是由哈希值排序的,实际上也是由以哈希 表大小
的条目排序的;在您的情况下,这应该接近自然排序,因为您只插入一个较小范围内的数字-
如果您从中取随机数randrange(10**10)而不是randrange(500)您应该会看到其他行为。另外,根据您的插入顺序,由于哈希冲突,您可以从其原始哈希顺序中获得一些值。



 类似资料:
  • 问题内容: 当他每次运行程序时都不断获得相同的数字时,我试图向Java解释随机数生成器。我为同一件事创建了自己的简单版本,每次运行该程序时,我也得到了与他得到的确切数字相同的数字。 我究竟做错了什么? 100个数字中的最后五个数字是: 问题答案: 您已经为随机数生成器提供了恒定的值。它是确定性的,因此每次运行都会生成相同的值。 我不确定您为什么选择使用作为种子,但是种子值与生成的值范围无关(这是由

  • 一个简单的新手问题,奇怪的是我一直没能找到解决方法。

  • 问题内容: 我正在尝试在Java中生成盐,以与用于安全密码存储的哈希算法配合使用。我正在使用以下代码创建随机盐: 这应该生成一个完全安全的,随机生成的盐,以用于我的哈希算法。但是,当我运行代码时,每次都会输出相同的盐…表示生成的盐根本不是随机的。 出于明显的安全性目的,每个用户都需要一个唯一的符号,但是如果我每次创建一个新帐户时都使用此代码,则每个用户都将具有相同的符号,这一开始就破坏了它的用途。

  • 我正在尝试模拟我在上面发现的数学难题http://blog.xkcd.com/2010/02/09/math-puzzle/.然而,java random类返回了奇怪的结果。在下面的代码中,结果是预期的。第一行的输出大约为.612,第二行的输出介于.49和.51之间。int试验=10000000;int成功=0; 然而,当我切换 到 第一个数字的输出约为 .476,第二个数字的输出约为 .710。

  • 问题内容: 我了解python集的元素没有顺序。调用pop方法将返回一个任意元素;我很好。 我想知道的是,当集合具有相同的历史记录时,pop是否总是返回相同的元素。当然,在一个版本的python中,我不介意不同版本的python实现自己的事情。特别是,我问的是python 2.7。在这种情况下,这比api的实现问题更多。 我在游戏的程序地牢生成器中大量使用了set,​​我希望结果对于给定的种子是确

  • Removes last element and returns it Returns: object element