相关疑难解决方法(0)

为什么Python 3中的"1000000000000000在范围内(1000000000000001)"如此之快?

据我所知,该range()函数实际上是Python 3中的一个对象类型,它可以动态生成其内容,类似于生成器.

在这种情况下,我预计下面的行会花费大量的时间,因为为了确定1千万亿是否在该范围内,必须生成一个千万亿的值:

1000000000000000 in range(1000000000000001)
Run Code Online (Sandbox Code Playgroud)

此外:似乎无论我添加多少个零,计算或多或少都需要相同的时间(基本上是瞬时的).

我也试过这样的事情,但计算仍然几乎是即时的:

1000000000000000000000 in range(0,1000000000000000000001,10) # count by tens
Run Code Online (Sandbox Code Playgroud)

如果我尝试实现自己的范围功能,结果就不那么好了!!

def my_crappy_range(N):
    i = 0
    while i < N:
        yield i
        i += 1
    return
Run Code Online (Sandbox Code Playgroud)

range()在引擎盖下做的对象是什么让它如此之快?


选择Martijn Pieters的答案是因为它的完整性,但也看到了abarnert的第一个答案,可以很好地讨论在Python 3中range成为一个完整的序列意味着什么,以及关于__contains__Python实现中函数优化的潜在不一致的一些信息/警告.abarnert的另一个答案更详细,并为那些对Python 3中的优化背后的历史感兴趣的人提供了链接(并且缺乏xrangePython 2中的优化).pokewim的答案感兴趣的人提供了相关的C源代码和解释.

python performance range python-3.x python-internals

1890
推荐指数
11
解决办法
18万
查看次数

为什么链接的运算符表达式比扩展的等效表达式慢?

在python中,可以以这种方式链接运算符:

a op b op c
Run Code Online (Sandbox Code Playgroud)

评估为

a op b and b op c 
Run Code Online (Sandbox Code Playgroud)

唯一的区别b是只评估一次(所以更像是t = eval(b); a op t and t op c).

从具有显式连接(使用)的等效版本可读且更简洁的观点来看,这是有利的and.

但是......我注意到链接表达式和等效表达式之间存在微小的性能差异,无论是3个操作数还是20个.当你计算这些操作时,这一点就变得很明显了.

import timeit 

timeit.timeit("a <= b <= c", setup="a,b,c=1,2,3")
0.1086414959972899

timeit.timeit("a <= b and b <= c", setup="a,b,c=1,2,3")
0.09434155100097996
Run Code Online (Sandbox Code Playgroud)

和,

timeit.timeit("a <= b <= c <= d <= e <= f", setup="a,b,c,d,e,f=1,2,3,4,5,6")
0.2151330839988077

timeit.timeit("a <= b and b <= c and c <= d and …
Run Code Online (Sandbox Code Playgroud)

python comparison python-internals

17
推荐指数
1
解决办法
374
查看次数