据我所知,该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中的优化背后的历史感兴趣的人提供了链接(并且缺乏xrange
Python 2中的优化).poke和wim的答案为感兴趣的人提供了相关的C源代码和解释.
在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)