为什么在Python 3中 “1000000000000000 in range(1000000000000001)” 如此之快?
为什么在Python 3中 “1000000000000000 in range(1000000000000001)” 如此之快?
技术背景
在Python 3中,range() 函数返回的是一个 range 对象,它与Python 2中的 xrange 类似,是一种可迭代对象。很多人认为 range() 函数像生成器一样,会在迭代时逐个生成值。因此,当使用 in 操作符检查一个非常大的数是否在 range 对象中时,可能会预期需要很长时间,因为要生成大量的值来进行判断。然而,实际情况是这个操作几乎是瞬间完成的,无论 range 对象的范围有多大。
实现步骤
理解 range 对象的特性
range 对象是一个智能的序列对象,它并不立即生成所有的值,而是在需要时根据起始值、结束值和步长来计算每个值。它实现了 __contains__ 方法,该方法会通过数学计算来判断一个数是否在 range 对象的范围内,而不是逐个生成值进行比较。
classmy_range: def__init__(self, start, stop=None, step=1, /): if stop isNone: start, stop = 0, start self.start, self.stop, self.step = start, stop, step if step < 0: lo, hi, step = stop, start, -step else: lo, hi = start, stop self.length = 0if lo > hi else ((hi - lo - 1) // step) + 1
def__iter__(self): current = self.start ifself.step < 0: while current > self.stop: yield current current += self.step else: while current < self.stop: yield current current += self.step
def__len__(self): returnself.length
def__getitem__(self, i): if i < 0: i += self.length if0 <= i < self.length: returnself.start + i * self.step raise IndexError('my_range object index out of range')