[英]Iterate over list starting from a certain index
下面是一個例子:
list_ = [5, 'cat', 0xDEADBEEF, 4.0]
for offset in range(len(list_)):
result = 0
for elem in list_[offset:]:
result = func(result, elem)
return result
其中func
是不可交換的。
在上面的代碼中, list_[offset:]
將創建一個新列表,但我需要的只是list_
的視圖。 我怎樣才能優化這個?
要復制您的切片,但每次迭代的時間為 O(1),您可以將collections.deque
與popleft
一起popleft
:
from collections import deque
dq = deque(list_)
for i in range(len(dq)):
print(dq)
dq.popleft()
結果:
deque([5, 'cat', 3735928559, 4.0])
deque(['cat', 3735928559, 4.0])
deque([3735928559, 4.0])
deque([4.0])
這應該比列表切片更有效:參見deque.popleft() 和 list.pop(0)。 有性能差異嗎? . 還要注意列表切片在 O( k ) 時間內工作,其中k是切片的長度。
正如@jpp 的回答所建議的那樣,使用collections.deque
有時會稍微快一些。 slice 和deque
解決方案的性能相似,並且list_
如使用itertools.islice
或僅在list_
上使用普通索引list_
。
我試圖使版本或多或少總體上相等,並使用了一個計算循環的虛擬func
:
from __future__ import print_function
from collections import deque
from itertools import islice
from timeit import repeat
import numpy as np
list_ = [5, 'cat', 0xDEADBEEF, 4.0]
list_3k = list_ * 3000
def func(x, y):
return x + 1
def f1():
"""list slice"""
result = 0
for offset in range(len(list_)):
for elem in list_[offset:]:
result = func(result, elem)
return result
def f2():
"""deque"""
dq = deque(list_)
result = 0
for i in range(len(dq)):
for elem in dq:
result = func(result, elem)
dq.popleft()
return result
def f3():
"""itertools slice"""
result = 0
for offset in range(len(list_)):
for elem in islice(list_, offset, None):
result = func(result, elem)
return result
def f4():
"""basics"""
result = 0
n = len(list_)
for offset in range(n):
j = offset
while j < n:
result = func(result, list_[j])
j += 1
return result
def timeit(fn, number):
print("{}: {} loops".format(fn.__name__, fn()))
times = repeat(fn, repeat=3, number=number)
print("{:.3f}s ± {:.3f}ms".format(np.mean(times), np.std(times)*1000))
if __name__ == "__main__":
fs = [f1, f2, f3, f4]
for f in fs:
timeit(f, number=1000000)
list_ = list_3k
print()
for f in fs:
timeit(f, number=3)
結果:
bash-3.2$ python3 foo.py
f1: 10 loops
2.161s ± 9.333ms
f2: 10 loops
2.134s ± 5.127ms
f3: 10 loops
2.340s ± 11.928ms
f4: 10 loops
2.315s ± 4.615ms
f1: 72006000 loops
23.073s ± 109.857ms
f2: 72006000 loops
23.495s ± 596.822ms
f3: 72006000 loops
24.432s ± 553.167ms
f4: 72006000 loops
40.509s ± 128.367ms
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.