在Python中通过切片进行有效的迭代
Python中切片操作的迭代效率如何?而且,如果不可避免地要有切片,那么有替代方法吗?
我知道列表上的切片操作为O(k),其中k是切片的大小。
x[5 : 5+k] # O(k) copy operation
但是,当遍历列表的一部分时,我发现执行此操作的最简洁的方法(也是最Python的?)(不必求助于索引)是:
for elem in x[5 : 5+k]:
print elem
但是,我的直觉是,这仍然会导致子列表的开销很大,而不是简单地遍历现有列表。
-
您可以用来
itertools.islice
从列表中获取切片式迭代器:例:
>>> from itertools import islice >>> lis = range(20) >>> for x in islice(lis, 10, None, 1): ... print x ... 10 11 12 13 14 15 16 17 18 19
更新:
正如@
user2357112所指出的那样,的性能islice
取决于切片的起点和可迭代的大小,在几乎所有情况下,普通切片都将很快,因此应首选。以下是一些时序比较:对于 巨大的名单
islice
是稍快或等于正常片时片的起点是列表中只有不到一半的大小,更大的指标正常切片是明显的赢家。>>> def func(lis, n): it = iter(lis) for x in islice(it, n, None, 1):pass ... >>> def func1(lis, n): #it = iter(lis) for x in islice(lis, n, None, 1):pass ... >>> def func2(lis, n): for x in lis[n:]:pass ... >>> lis = range(10**6) >>> n = 100 >>> %timeit func(lis, n) 10 loops, best of 3: 62.1 ms per loop >>> %timeit func1(lis, n) 1 loops, best of 3: 60.8 ms per loop >>> %timeit func2(lis, n) 1 loops, best of 3: 82.8 ms per loop >>> n = 1000 >>> %timeit func(lis, n) 10 loops, best of 3: 64.4 ms per loop >>> %timeit func1(lis, n) 1 loops, best of 3: 60.3 ms per loop >>> %timeit func2(lis, n) 1 loops, best of 3: 85.8 ms per loop >>> n = 10**4 >>> %timeit func(lis, n) 10 loops, best of 3: 61.4 ms per loop >>> %timeit func1(lis, n) 10 loops, best of 3: 61 ms per loop >>> %timeit func2(lis, n) 1 loops, best of 3: 80.8 ms per loop >>> n = (10**6)/2 >>> %timeit func(lis, n) 10 loops, best of 3: 39.2 ms per loop >>> %timeit func1(lis, n) 10 loops, best of 3: 39.6 ms per loop >>> %timeit func2(lis, n) 10 loops, best of 3: 41.5 ms per loop >>> n = (10**6)-1000 >>> %timeit func(lis, n) 100 loops, best of 3: 18.9 ms per loop >>> %timeit func1(lis, n) 100 loops, best of 3: 18.8 ms per loop >>> %timeit func2(lis, n) 10000 loops, best of 3: 50.9 us per loop #clear winner for large index >>> %timeit func1(lis, n)
对于 小型列表, 普通切片比
islice
几乎所有情况下都快。>>> lis = range(1000) >>> n = 100 >>> %timeit func(lis, n) 10000 loops, best of 3: 60.7 us per loop >>> %timeit func1(lis, n) 10000 loops, best of 3: 59.6 us per loop >>> %timeit func2(lis, n) 10000 loops, best of 3: 59.9 us per loop >>> n = 500 >>> %timeit func(lis, n) 10000 loops, best of 3: 38.4 us per loop >>> %timeit func1(lis, n) 10000 loops, best of 3: 33.9 us per loop >>> %timeit func2(lis, n) 10000 loops, best of 3: 26.6 us per loop >>> n = 900 >>> %timeit func(lis, n) 10000 loops, best of 3: 20.1 us per loop >>> %timeit func1(lis, n) 10000 loops, best of 3: 17.2 us per loop >>> %timeit func2(lis, n) 10000 loops, best of 3: 11.3 us per loop
结论:
去正常切片。