Ric*_*ica -3 python optimization range python-3.x
从前一个问题跳出来,我问了一会儿:
为什么Python 3中的1000000000000000范围(1000000000000001)如此之快?
如果你这样做:
1000000000000000.0 in range(1000000000000001)
Run Code Online (Sandbox Code Playgroud)
...很明显,range
尚未进行优化以检查float
s是否在指定范围内.
我想我明白,预期的目的range
是int
仅使用s - 所以你不能,例如,做这样的事情:
1000000000000 in range(1000000000000001.0)
# error: float object cannot be interpreted as an integer
Run Code Online (Sandbox Code Playgroud)
或这个:
1000000000000 in range(0, 1000000000000001, 1.0)
# error: float object cannot be interpreted as an integer
Run Code Online (Sandbox Code Playgroud)
然而,无论出于何种原因,决定允许这样的事情:
1.0 in range(1)
Run Code Online (Sandbox Code Playgroud)
似乎很明显1.0
(及1000000000000.0
以上)没有被强制转换为int
s,因为那时int
优化也适用于那些.
我的问题是,为什么不一致,为什么没有优化float
s?或者,或者,为什么上述代码不会产生与前面示例相同的错误的原因是什么?
除了优化int
s 之外,这似乎是一个明显的优化.我猜测有一些细微的问题妨碍了这种优化的干净实施,或者有一些理由说明为什么你实际上不想包含这样的优化.或者两者都可能.
编辑:为了澄清这里的问题,以下所有语句都进行了评估False
:
3.2 in range(5)
'' in range(1)
[] in range(1)
None in range(1)
Run Code Online (Sandbox Code Playgroud)
这似乎是我意想不到的行为,但到目前为止肯定没有不一致.但是,以下评估结果为True
:
1.0 in range(2.0)
Run Code Online (Sandbox Code Playgroud)
并且如前所示,与上述类似的结构尚未优化.
这似乎是不一致的 - 在评估的某个时刻,价值1.0
(或者1000000000001.0
在我的原始例子中)被强制转换为int
.这是有道理的,因为它是一个转换自然的事情float
结局的.0
一个int
.然而,问题仍然存在:如果它正在被转换int
,为什么还1000000000000.0 in range(1000000000001)
没有进行优化?
这里没有矛盾.浮点值不能强制转换为整数,只能以相反的方式工作.因此,range()
在测试包容时,不会隐式地将浮点数转换为整数.
甲range()
对象是一个序列类型 ; 它包含离散的整数值(尽管是虚拟的).因此,它必须支持对可能测试相同的任何对象的包含测试.以下也适用:
>>> class ThreeReally:
... def __eq__(self, other):
... return other == 3
...
>>> ThreeReally() in range(4)
True
Run Code Online (Sandbox Code Playgroud)
这必须对范围内的所有可能值进行全面扫描,以测试与每个包含的整数的相等性.
但是,只有在使用实际整数时才能应用优化,因为这是range()
对象可以知道在没有转换的情况下将被视为相等的唯一类型.