Python,len和整数的大小

时间:2010-01-24 21:40:34

标签: python int

因此,当某事物的长度接近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))很糟糕。我猜这里有一些浮点行为(被视为负面)行动。

  1. 这到底发生了什么? (这在下面很好解决!)
  2. 我怎样才能解决这个问题?多头?
  3. (如果有人想直接解决这个问题,我的具体申请是random.sample(xrange(1<<32),ABUNCH))。)

3 个答案:

答案 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,当被视为有符号整数时,是否定的。