【问题标题】:Iterate a huge list of integers which grow exponentially, where the exponent is 1.5迭代一个指数增长的巨大整数列表,其中指数为 1.5
【发布时间】:2020-04-22 19:36:08
【问题描述】:

我需要迭代一个整数列表:

2, 3, 4, 6, 9, 13, 19, 28, 42, ...

所以一般规则是list[i+1] = list[i]*3/2

列表应在 10^34 或之前结束。

这意味着最后一个元素是介于 10^34*2/3 和 10^34 之间的数字。

我显然不能在内存中预先分配这个列表,所以类似于:

list = [2]
while True:
    next = list[-1]*3/2
    if next > 10**34:
        break
    list.append(next)

不可能。

我当然可以简单地使用上述方法来迭代这些整数,而无需将它们存储在列表中或由某种迭代器生成。

但问题是我有嵌套循环,像这样:

for i in xrange(...):
    for j in xrange(...):
        for m in xrange(...):
            for n in xrange(...):

因此,将其分解为几个 while 循环会使代码变得非常糟糕。

理想情况下,我想要某种xrange,它会“即时”生成这个数字列表(就像xranges 通常那样)。

【问题讨论】:

  • 其实列表不会很大:math.log(10 ** 34, 1.5) 返回 193。
  • @timchap:哎呀!!!!所以我也可以使用range。知道如何以pythonic方式生成它(即在一行中)吗?谢谢
  • @timchap:有趣的是,在问这个问题之前,我已经在浏览器中打开了wolfram with this computation

标签: python python-2.7


【解决方案1】:

正如我在评论中提到的,该列表实际上不会很长。因此,您可以将其初始化为:

[int(2 * (1.5 ** n)) for n in range(int(math.log(10 ** 34, 1.5) - 1))]

但是,这实际上与您给出的示例略有不同,在该示例中,您在生成下一个数字之前取整为整数。在这种情况下,您将不得不做一些迭代(据我所知):

i = 2
lst = []
while i < 10 ** 34:
    lst.append(i)
    i = int(i * 1.5)

【讨论】:

  • 上面的-1 应该是+1 IMO。
  • 嗯,我正在根据您的要求“列表应在 10^34 或之前结束”。列表中最后一个使用-1 的数字是8.599248e+33,最后一个使用+1 的数字是1.934831e+34
【解决方案2】:

这可能是您正在寻找的:

lst = [2*1.5**i for i in range(0,192)]

最后一项是 2*1.5^191。

如果你希望它们都是整数,你可以说使用 int() 强制转换。

但您应该注意,执行此操作的时间/内存可能与您在示例代码中所做的类似。他们最终都在做类似的事情。

如果您希望它们在整个过程中都是整数:

i = 2
lst = [2]
while i < 10**34:
    lst.append(int(i*=1.5))

同样,这只会节省微量的内存/时间。

【讨论】:

  • 这应该是 192,因为 QA 要求它在 10 ^ 34 之前停止。我认为这与我的答案重复,没有 math.log
  • 这不会生成整数的列表!即使您将其转换为int,那么这些整数也不一定与每个整数都是前一个整数乘以 1.5 的底值的列表相同。
  • 我不知道这是您想要做的。在您的示例代码中,您实际上根本没有将任何内容转换为 int,所以我只是遵循了这一点
猜你喜欢
  • 2019-02-16
  • 2015-10-18
  • 1970-01-01
  • 1970-01-01
  • 2017-08-05
  • 2016-11-28
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多