`xrange(2**100)` ->溢出错误:long int 太大而无法转换为 int [英] `xrange(2**100)` -> OverflowError: long int too large to convert to int

查看:32
本文介绍了`xrange(2**100)` ->溢出错误:long int 太大而无法转换为 int的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

xrange 函数不适用于大整数:

<预><代码>>>>N = 10**100>>>范围(N)回溯(最近一次调用最后一次):...溢出错误:long int 太大而无法转换为 int>>>xrange(N, N+10)回溯(最近一次调用最后一次):...溢出错误:long int 太大而无法转换为 int

Python 3.x:

<预><代码>>>>N = 10**100>>>r = 范围(N)>>>r = 范围(N,N+10)>>>连(右)10

是否有用于 Python 2.x 的 py3k 内置 range() 函数的反向移植?

编辑

我正在寻找懒惰"range() 的完整实现,而不仅仅是其某些功能的部分实现.

解决方案

好的,这是一个更完整的重新实现.

class MyXRange(object):def __init__(self, a1, a2=None, step=1):如果步骤 == 0:raise ValueError("arg 3 不能为 0")如果 a2 是 None:a1, a2 = 0, a1如果 (a2 - a1) % 步 != 0:a2 += 步 - (a2 - a1) % 步如果 cmp(a1, a2) != cmp(0, step):a2 = a1self.start, self.stop, self.step = a1, a2, stepdef __iter__(self):n = self.start而 cmp(n, self.stop) == cmp(0, self.step):产量 nn += self.stepdef __repr__(self):return "MyXRange(%d,%d,%d)" % (self.start, self.stop, self.step)# 注意:len(self) 会将其转换为 int,并且可能会失败def __len__(self):返回(self.stop - self.start)//(self.step)def __getitem__(self, key):如果键<0:键 = self.__len__() + 键如果键<0:raise IndexError("列表索引超出范围")返回自己[key]n = self.start + self.step*key如果 cmp(n, self.stop) != cmp(0, self.step):raise IndexError("列表索引超出范围")返回 ndef __reversed__(self):返回 MyXRange(self.stop-self.step, self.start-self.step, -self.step)def __contains__(self, val):if val == self.start: return cmp(0, self.step) == cmp(self.start, self.stop)如果 cmp(self.start, val) != cmp(0, self.step): 返回 False如果 cmp(val, self.stop) != cmp(0, self.step): 返回 False返回 (val - self.start) % self.step == 0

还有一些测试:

def testMyXRange(testsize=10):def normexcept(f,args):尝试:r = [f(args)]除了例外,e:r = 类型(e)返回对于我在范围内(-testsize,testsize+1):对于范围内的 j(-testsize,testsize+1):打印 i, j对于范围内的 k (-9, 10, 2):r, mr = range(i,j,k), MyXRange(i,j,k)如果 r != 列表(先生):打印迭代失败:%d、%d、%d"%(i,j,k)if list(reversed(r)) != list(reversed(mr)):打印反向失败:%d, %d, %d" % (i,j,k)如果 len(r) != len(mr):打印 "len 失败: %d, %d, %d" % (i,j,k)z = [m for m in range(-testsize*2,testsize*2+1)if (m in r) != (m in mr)]如果 z != []:打印包含失败:%d, %d, %d, %s" % (i,j,k,(z+["..."])[:10])z = [m for m in range(-testsize*2, testsize*2+1)if normexcept(r.__getitem__, m) != normexcept(mr.__getitem__, m)]如果 z != []:打印 "getitem 失败: %d, %d, %d, %s" % (i,j,k,(z+["..."])[:10])

xrange function doesn't work for large integers:

>>> N = 10**100
>>> xrange(N)
Traceback (most recent call last):
...
OverflowError: long int too large to convert to int
>>> xrange(N, N+10)
Traceback (most recent call last):
...
OverflowError: long int too large to convert to int

Python 3.x:

>>> N = 10**100
>>> r = range(N)
>>> r = range(N, N+10)
>>> len(r)
10

Is there a backport of py3k builtin range() function for Python 2.x?

Edit

I'm looking for a complete implementation of "lazy" range(), not just a partial implementation of some of its functionality.

解决方案

Okay, here's a go at a fuller reimplementation.

class MyXRange(object):
    def __init__(self, a1, a2=None, step=1):
        if step == 0:
            raise ValueError("arg 3 must not be 0")
        if a2 is None:
            a1, a2 = 0, a1
        if (a2 - a1) % step != 0:
            a2 += step - (a2 - a1) % step
        if cmp(a1, a2) != cmp(0, step):
            a2 = a1
        self.start, self.stop, self.step = a1, a2, step

    def __iter__(self):
        n = self.start
        while cmp(n, self.stop) == cmp(0, self.step):
            yield n
            n += self.step

    def __repr__(self):
        return "MyXRange(%d,%d,%d)" % (self.start, self.stop, self.step)

    # NB: len(self) will convert this to an int, and may fail
    def __len__(self):
        return (self.stop - self.start)//(self.step)

    def __getitem__(self, key):
        if key < 0:
            key = self.__len__() + key
            if key < 0:
                raise IndexError("list index out of range")
            return self[key]
        n = self.start + self.step*key
        if cmp(n, self.stop) != cmp(0, self.step):
            raise IndexError("list index out of range")
        return n

    def __reversed__(self):
        return MyXRange(self.stop-self.step, self.start-self.step, -self.step)

    def __contains__(self, val):
        if val == self.start: return cmp(0, self.step) == cmp(self.start, self.stop)
        if cmp(self.start, val) != cmp(0, self.step): return False
        if cmp(val, self.stop) != cmp(0, self.step): return False
        return (val - self.start) % self.step == 0

And some testing:

def testMyXRange(testsize=10):
    def normexcept(f,args):
        try:
            r = [f(args)]
        except Exception, e:
            r = type(e)
        return r

    for i in range(-testsize,testsize+1):
        for j in range(-testsize,testsize+1):
            print i, j
            for k in range(-9, 10, 2):
                r, mr = range(i,j,k), MyXRange(i,j,k)

                if r != list(mr):
                    print "iter fail: %d, %d, %d" % (i,j,k)

                if list(reversed(r)) != list(reversed(mr)):
                    print "reversed fail: %d, %d, %d" % (i,j,k)

                if len(r) != len(mr):
                    print "len fail: %d, %d, %d" % (i,j,k)

                z = [m for m in range(-testsize*2,testsize*2+1)
                      if (m in r) != (m in mr)]
                if z != []:
                    print "contains fail: %d, %d, %d, %s" % (i,j,k,(z+["..."])[:10])

                z = [m for m in range(-testsize*2, testsize*2+1) 
                      if normexcept(r.__getitem__, m) != normexcept(mr.__getitem__, m)]
                if z != []:
                    print "getitem fail: %d, %d, %d, %s" % (i,j,k,(z+["..."])[:10])

这篇关于`xrange(2**100)` ->溢出错误:long int 太大而无法转换为 int的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆