为什么没有为浮点数优化Python 3范围对象?

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尚未进行优化以检查floats是否在指定范围内.

我想我明白,预期的目的rangeint仅使用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以上)没有被强制转换为ints,因为那时int优化也适用于那些.

我的问题是,为什么不一致,为什么没有优化floats?或者,或者,为什么上述代码不会产生与前面示例相同的错误的原因是什么?

除了优化ints 之外,这似乎是一个明显的优化.我猜测有一些细微的问题妨碍了这种优化的干净实施,或者有一些理由说明为什么你实际上不想包含这样的优化.或者两者都可能.

编辑:为了澄清这里的问题,以下所有语句都进行了评估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)没有进行优化?

Mar*_*ers 5

这里没有矛盾.浮点值不能强制转换为整数,只能以相反的方式工作.因此,range()在测试包容时,不会隐式地将浮点数转换为整数.

range()对象是一个序列类型 ; 它包含离散的整数值(尽管是虚拟的).因此,它必须支持对可能测试相同的任何对象的包含测试.以下也适用:

>>> class ThreeReally:
...     def __eq__(self, other):
...         return other == 3
...
>>> ThreeReally() in range(4)
True
Run Code Online (Sandbox Code Playgroud)

这必须对范围内的所有可能值进行全面扫描,以测试与每个包含的整数的相等性.

但是,只有在使用实际整数时才能应用优化,因为这是range()对象可以知道在没有转换的情况下将被视为相等的唯一类型.

  • @RickTeachey:不,序列的文档声明`in`测试对象中是否有相等的值.`1.0 == 1`是相等的,所以`1.0 in range(10)`是真的,因为该序列中有一个相等的值.Python只是不*优化它,因为它需要一个隐式转换,而不是范围对象的用例. (2认同)