因此,当某事物的长度接近1 <&lt; 32(int的大小)时,cPython(2.4)会有一些有趣的行为。
r = xrange(1<<30)
assert len(r) == 1<<30
很好,但是:
r = xrange(1<<32)
assert len(r) == 1<<32
ValueError: xrange object size cannot be reported`__len__() should return 0 <= outcome
Alex的wowrange也有这种行为。 wowrange(1<<32).l
很好,但len(wowrange(1<<32))
很糟糕。我猜这里有一些浮点行为(被视为负面)行动。
(如果有人想直接解决这个问题,我的具体申请是random.sample(xrange(1<<32),ABUNCH))
。)
答案 0 :(得分:11)
cPython假设列表适合内存。这扩展到行为类似于列表的对象,例如xrange。实质上,len
函数期望__len__
方法返回可转换为size_t
的内容,如果逻辑元素的数量太大,即使这些元素没有,也不会发生实际上存在于记忆中。
答案 1 :(得分:5)
你会发现
xrange(1 << 31 - 1)
是最后一个符合您的行为。这是因为最大有符号(32位)整数是2 ^ 31 - 1。
1 << 32
不是带正号的32位整数(Python的int
数据类型),所以这就是你得到错误的原因。
在Python 2.6中,我甚至无法在没有收到错误的情况下执行xrange(1 << 32)
或xrange(1 << 31)
,更不用说len
了。{/ p>
修改如果您想了解更多细节......
1 << 31
表示数字0x80000000,其中2的补码表示是32位int
的最低可表示负数(-1 * 2 ^ 31)。所以,是的,由于您正在使用的数字的位数表示,它实际上变为负数。
对于32位2的补码数,0x7FFFFFFF是最大可表示的整数(2 ^ 31 - 1),然后“溢出”为负数。
Further reading,如果您有兴趣的话。
请注意,当您在提示符中看到类似2147483648L的内容时,末尾的“L”表示它现在被表示为“长整数”(64位,通常,我不能对Python如何做出任何承诺处理它,因为我还没有读过它。)
答案 2 :(得分:1)
1<<32
,当被视为有符号整数时,是否定的。