【问题标题】:Strange result when calling function with iteration over elements of a list使用迭代列表元素调用函数时出现奇怪的结果
【发布时间】:2022-01-02 10:29:39
【问题描述】:

我为生日问题定义了一个非常简单的函数:

from math import comb, factorial
import numpy as np

def birthday(k):
    return 1-((factorial(k)*comb(365,k))/(365**k))

该功能有效,因为k=23 给出:

[in] birthday(23)
[out] 0.5072972343239854

我想用 k 从 1 到 50 迭代列表并将概率结果保存到列表 prob,如下所示:

klist=np.arange(1,51)
prob=[]
for k in klist:
    prob.append(birthday(k))

对于 k=1 到 k=7,没有问题,但从 k=8 开始,突然输出对于非常大的负值不再有意义。我在这里做错了什么? (显示 k=1 到 10 的输出)

[ 1 2 3 4 5 6 7 8 9 10 ]

[0.0, 0.002739726027397249, 0.008204165884781345, 0.016355912466550326, 0.02713557369979358, 0.040462483649111536, 0.056235703095975365, -203.08817475498518, -20769.916905383445, -11786425.811859423]

但是,只是运行: [in] birthday(10) 给出正确的: [out] 0.11694817771107768

【问题讨论】:

  • 我认为这与numpy的int32和python的int之间的差异有关。因为如果你这样做 prob.append(birthday(int(k))) 它工作正常。所以也许可以考虑一下。

标签: python list function loops


【解决方案1】:

问题在于使用这个:

klist=np.arange(1,51)

这使得每次调用 birthday 时 k 成为 numpy.int32。如果你试试这个:

print(birthday(np.int32(10)))

你会发现有同样的问题。

这可行:

from math import comb, factorial
import numpy as np


def birthday(k):
    return 1-((factorial(k)*comb(365,k))/(365**k))


prob=[]
for k in range(51):
    prob.append(birthday(k))

一个 32 位整数似乎不足以容纳 birthday() 计算的值,并且会出现溢出。

【讨论】:

  • 很棒的发现。事实上,它甚至可以创建一个 numpy.int64 (当我调用 type(klist[8]) 时。我可以只用 int 创建一个列表吗?非常感谢!编辑:我通过添加一行在 for 循环中创建了带有整数的 klist klist.append(k)
  • 是的,简单地使用klist = list(range(51)) 将是一个带有Python int 的列表,它的大小没有真正的限制(尽管性能当然是有限的)。在您的示例中,您实际上并不需要列表,您可以按照我的指示在 range 生成器上使用 for,但也许您的代码中的其他地方也需要列表,那么我的建议应该可行。
  • 确实,再次感谢!
  • 如果这回答了您的问题,请点击答案旁边的复选标记,这样问题就不再显示为未回答
猜你喜欢
  • 2022-01-24
  • 1970-01-01
  • 1970-01-01
  • 2015-01-18
  • 1970-01-01
相关资源
最近更新 更多