Python,len和整数的大小

Gre*_*ind 5 python int

因此,当某事物的长度接近1 << 32(int的大小)时,cPython(2.4)会有一些有趣的行为.

r = xrange(1<<30)
assert len(r) == 1<<30
Run Code Online (Sandbox Code Playgroud)

很好,但是:

r = xrange(1<<32)
assert len(r) == 1<<32
ValueError: xrange object size cannot be reported`__len__() should return 0 <= outcome
Run Code Online (Sandbox Code Playgroud)

Alex的wowrange也有这种行为. wowrange(1<<32).l很好,但 len(wowrange(1<<32))很糟糕.我猜这里有一些浮点行为(被视为负面)行动.

  1. 到底发生了什么?(这在下面很好解决!)
  2. 我怎么能绕过它呢? 多头?

(我的具体应用是,random.sample(xrange(1<<32),ABUNCH))如果人们想直接解决这个问题!)

Sin*_*ion 11

cPython假设列表适合内存.这扩展到行为类似于列表的对象,例如xrange.实质上,len函数期望__len__方法返回可转换的东西,size_t如果逻辑元素的数量太大,即使这些元素实际上不存在于内存中,也不会发生这种情况.


Sap*_*pph 5

你会发现的

xrange(1 << 31 - 1)
Run Code Online (Sandbox Code Playgroud)

是最后一个表现你想要的.这是因为最大有符号(32位)整数是2 ^ 31 - 1.

1 << 32不是一个正的带符号32位整数(Python的int数据类型),所以这就是你得到那个错误的原因.

在Python 2.6中,我甚xrange(1 << 32)xrange(1 << 31)无法获得或不获取错误,更不用说len结果了.

编辑如果你想要更多细节......

1 << 31表示数字0x80000000,其中2的补码表示是32位的最低可表示负数(-1*2 ^ 31)int.所以,是的,由于您正在使用的数字的逐位表示,它实际上变为负面.

对于32位2的补码数,0x7FFFFFFF是在"溢出"为负数之前可表示的最大整数(2 ^ 31 - 1).

如果你有兴趣,请进一步阅读.

请注意,当您在提示符中看到类似2147483648L的内容时,末尾的"L"表示它现在被表示为"长整数"(64位,通常,我无法对Python如何处理它做出任何承诺,因为我没有读过它).