【问题标题】:Birthday Paradox List is nonetype生日悖论列表是非类型的
【发布时间】:2012-04-29 17:28:23
【问题描述】:

我正在尝试用 Python 解决生日悖论。我很接近,但最后一块让我不知所措。我正在使用 random 来生成给定范围和要创建的项目数量的数字列表。这行得通。

然后我检查列表(上面生成的)是否有重复项。这行得通。

然后我尝试生成给定的 (n) 个列表。这是我遇到麻烦的地方。它生成一个列表然后返回“NoneType”是不可迭代的。令我困惑的是,列表已生成,但 Python 并未将其视为列表。

代码如下:

def make_bd(n, r):
    """Generates (r) numbers of birthdays in a range (n)."""
    import random
    t = [random.randrange(n) for i in range(r)]
    print (t)


def has_dupe(test):
    """Here I test to see if I can detect a duplicate birthday.
This is based on problem #4."""

    d = []
    count = 0
    for number in test:
        if number in d:
            count = count + 1
        d.append(number)
    if count >= 1:
        return True
    return False

def dupebd(n,r,t):
    count_dupe = 0
    for i in range(n):
        if has_dupe(make_bd(r,t)):
            count_dupe = count_dupe + 1
    print (float(count)/n)       

dupebd(50,365,23)

结果如下:

>>> has_dupe(make_bd(50,6))
[13, 3, 8, 29, 34, 44]
Traceback (most recent call last):
  File "<pyshell#45>", line 1, in <module>
    has_dupe(make_bd(50,6))
  File "<pyshell#44>", line 7, in has_dupe
    for number in test:
TypeError: 'NoneType' object is not iterable

【问题讨论】:

  • 请注意,如果在has_dupe 中使用集合而不是d 的列表,则您的算法将快得多,因为对集合中成员资格的测试比在列表中快得多。您还可以通过在找到一个重复项后立即返回 True 来缩短操作。您也可以对len(set(test)) == len(test) 行进行相同的测试,因为集合不包含重复项。

标签: python birthday-paradox


【解决方案1】:

在第 5 行打印 t 但不返回它,因此 make_bd 返回 None。将行改为

return t

【讨论】:

  • 就是这样!我在最后一个打印语句中也有 count_dupe 错误命名,但添加 return 修复了 NoneType 问题。谢谢!
【解决方案2】:
from random import randint

def make_bd(n, d):
    """Generates n birthdays in range(d)."""
    return [randint(1, d) for _ in xrange(n)]

def has_dupe(bd):
    """Test to see if list of birthdays contains one or more duplicates.
        This is based on problem #4.
    """
    return len(set(bd)) < len(bd)

def dupe_bd(n, d, t):
    dupes = sum(has_dupe(make_bd(n,d)) for _ in xrange(t))
    return dupes/float(t)

def exactProbability(n, d):
    probUnique = 1.0
    d = float(d)
    for i in xrange(n):
        probUnique *= (d - i)/d
    return 1.0 - probUnique

for n in xrange(18,26):
    print("{:d} people: {:0.4f} probability of shared birthday (exact: {:0.4f})".format(n, dupe_bd(n, 365, 1000), exactProbability(n, 365)))

给予

18 people: 0.3640 probability of shared birthday (exact: 0.3469)
19 people: 0.3790 probability of shared birthday (exact: 0.3791)
20 people: 0.4020 probability of shared birthday (exact: 0.4114)
21 people: 0.4070 probability of shared birthday (exact: 0.4437)
22 people: 0.4720 probability of shared birthday (exact: 0.4757)
23 people: 0.4980 probability of shared birthday (exact: 0.5073)
24 people: 0.5290 probability of shared birthday (exact: 0.5383)
25 people: 0.5450 probability of shared birthday (exact: 0.5687)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-06-23
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多