我正在做一个难题,我必须处理10 ^ 18的订单数量。但是,我发现python无法在所有区域处理非常大的数字。
具体来说,如果我们分配一个= 1000000000000000000(10 ^ 18)并进行基本的算术运算(+, - ,/,*),它的响应。但是,当我在range()
中使用它时,它显示出OverflowError>>> a = 1000000000000000000
>>> a/2
500000000000000000L
>>> a*2
2000000000000000000L
>>> a+a
2000000000000000000L
>>> a*a
1000000000000000000000000000000000000L
>>> range(a)
Traceback (most recent call last):
File "<pyshell#5>", line 1, in <module>
range(a)
OverflowError: range() result has too many items
>>> xrange(a)
Traceback (most recent call last):
File "<pyshell#6>", line 1, in <module>
xrange(a)
OverflowError: Python int too large to convert to C long
我使用的是Python 2.7。
我想在python 2.7中使用inbuild函数来完成它。这不可能吗?
答案 0 :(得分:10)
在Python 2.x中,range
和xrange
仅限于使用C long
,而您的大整数对此来说太大了。此限制仅仅是由于range
和xrange
的实施选择。
在Python 3.x中,限制已被删除,您可以使用非常大的整数执行range()
。
>>> range(2**128)
range(0, 340282366920938463463374607431768211456)
official list of changes for Python 3有这样说:
range()
现在的行为类似于xrange()
,但它适用于任意大小的值。后者不再存在。
在Python 2.x中,range()
函数返回了一个列表。显然,没有希望为非常大范围的所有元素分配内存。 xrange()
函数返回xrange
个对象。 documentation将其描述为“一个不透明的序列类型,它产生与相应列表相同的值,而不是实际同时存储它们”。文档继续这样说:
xrange()
旨在简单快捷。实现可能会对此实施限制。 Python的C实现将所有参数限制为本机C long(“短”Python整数),并且还要求元素的数量适合本机C long。
这解释了Python 2.x中的限制。
我不太清楚你可以用非常大范围的新Python 3支持做些什么。例如,我不建议你试试这个:
2**128 in range(2**128)
这将持续很长时间。
您在评论中指出您正在编写代码以计算大量数字。您可以使用以下代码在Python中轻松完成此任务:
i = 0
while i<N:
doSomething(i)
i += 1
但你会发现如果N
是一个很大的数字,那么这将需要很长时间。根据您的问题,对于2 18 的N
值,没有任何解决方法。
答案 1 :(得分:1)
你的问题是Python 2.7中的range()构造了一个范围内每个值的显式列表 - 你根本没有足够的资源来构建这样的列表。
Python 3纠正了这种行为 - 并且只根据需要计算值......就像生成器表达式一样。
Python 2 xrange()函数不会对你有所帮助,因为它被约束为注册值...这对Python 2来说是一种妥协,以避免任何非平凡数字的范围()的巨大开销小。
一种方法可能是定义自己的生成器,它迭代任意整数 - 类似于:
def genrange(min,max,stride=1):
val=min
while val<max:
yield val
val+=stride
然而,我怀疑这可能是更大的方案中的错误 - 因为你不可能有足够的处理资源来迭代32位整数中的每个值 - 更不用说整数范围更大了而不是(32位)寄存器。我怀疑有一种更好的方法可以解决你的问题,而不是首先取决于范围。