Python - 大数字

时间:2015-10-14 18:36:30

标签: python python-2.7 largenumber

无论如何都要运行范围超过13个字符的for循环? 例如:

for i in range (1000000000000):

我知道这不起作用,但它有什么办法吗?

4 个答案:

答案 0 :(得分:3)

对于python 2.7,请使用xrange(使用生成器而不是初始化大型列表):

for i in xrange(1000000000000):

答案 1 :(得分:3)

使用xrange也可以为您提供Python int too large to convert to C long错误,因为该号码必须符合C长度。要克服这种情况,请使用itertools.count创建自己的范围:

  from itertools import count

def myx_range(start, end):
    return iter(count(start).next, end)

如果你想在python 3中使用相同的逻辑:

from itertools import count

def myx_range(start, end):
    cn = count(start)
    return iter(lambda: next(cn), end)

while循环:

from itertools import count

def myx_range(start, end):
    while start < end:
        yield start
        start += 1

Windows上的32bit长,因此您将使用数字较大的xrange达到限制。

请参阅what-is-the-bit-size-of-long-on-64-bit-windows

答案 2 :(得分:0)

如果边界和步长在[-sys.maxsize-1,sys.maxsize]范围内,并且元素总数为<= sys.maxsize,那么xrange可以覆盖您。

如果没有,itertools提供了完全重新实现xrange所需的部分(并且也有效地将所有工作推送到CPython中的C层)以用于生成(xrange是一个真实的对象可以反复生成并支持一些其他功能;这只会生成,每次调用只能执行一次):

from itertools import count, islice

def myxrange(stop, *args):
    '''Replacement for xrange to generate ranges of arbitrarily large numbers efficiently
    '''
    start, step = 0, 1  # Defaults when only one argument passed
    if args:
        if len(args) > 2:
            raise TypeError("myxrange expected at most 3 arguments, got {}".format(len(args)))
        start = stop  # When 2+ args passed, stop is really start
        stop, step = (args + (1,))[:2]  # Use step if given, otherwise 1
    # islice slices x items, we need to calculate the number to slice
    # from the bounds given
    numitems = (stop - start + (step - (1 if step > 0 else -1))) // step
    return islice(count(start, step), numitems)

除了默认值1之外,上述处理step显然有些过分。如果不需要step支持,可以大大简化。

在CPython(参考解释器)中,这应该比使用Python级代码(需要重复执行字节代码)更有效;初始化后,islicecount会在C层完成所有工作,这可以显着提高效果。例如,与其他答案中基于while的循环相比,在我的机器上运行Python 2.7的ipython中:

>>> %timeit -r5 list(xrange(10, 2000))
100000 loops, best of 5: 15.2 μs per loop
>>> %timeit -r5 list(myxrange(10, 2000)) # Version in my answer
10000 loops, best of 5: 24.9 μs per loop
>>> %timeit -r5 list(myxrange2(10, 2000)) # Version using while from Padraig's answer
1000 loops, best of 5: 173 μs per loop

# Padraig's count based version takes 124 μs, though it could be optimized
# down to ~59 μs by changing it to the C layer version (though either
# version breaks if start > stop):
def myxrange(start, stop):
    return iter(count(start).next, end)

即使有模仿xrange非标准参数原型的开销,count + islice代码的开销仅比xrange高出约50%,因为它实际上处理了xrange无法实现的方案,所以并不是一半。

答案 3 :(得分:-1)

请记住,存储在处理器寄存器中的最小值和最大值存在限制。这意味着并非所有模块都可以接收大数字作为参数。