[英]How do you cycle a Python list to extend it from M to N values (M < N)?
我有一個元素列表 N,我想重復遍歷它直到它有 M 個元素,其中 M 可以是任何 integer,不一定是 N 的 integer 倍數。
我找到了兩種方法來做到這一點,但似乎都沒有我想象的那么直接。 在 Python 中有沒有更原生的方法來做到這一點?
這是我想出的。 請注意,第一種方法在有限的測試中更快。
from math import ceil
def repeat_list_1(values, n):
repeated = values * ceil(n / len(values))
return repeated[:n]
from itertools import cycle
def repeat_list_2(values, n):
values_cycler = cycle(values)
repeated = [next(values_cycler) for _ in range(n)]
return repeated
values = list(range(5))
n = 12
repeated1 = repeat_list_1(values, n)
repeated2 = repeat_list_2(values, n)
assert repeated1 == repeated2
print(repeated1)
[0, 1, 2, 3, 4, 0, 1, 2, 3, 4, 0, 1, 2]
如前所述,有多種方法可以實現這一目標,您必須根據一些標准(速度、代碼簡單性......)選擇您最喜歡的一種。
這是我覺得很簡單的一個(雖然它是舊式的 - 它不使用生成器):
>>> def repeat_list_4(values, n): ... d, m = divmod(n, len(values))... return values * d + values[:m]... >>> >>> repeat_list_4(list(range(5)), 12) [0, 1, 2, 3, 4, 0, 1, 2, 3, 4, 0, 1] >>> repeat_list_4(list(range(5)), 5) [0, 1, 2, 3, 4] >>> repeat_list_4(list(range(5)), 1) [0] >>> repeat_list_4(list(range(5)), 0) []
作為旁注,在您的示例中有n = 12
,但結果列表有13 個元素。
您可以使用islice
獲取可迭代的前n
值(在某些其他語言中稱為take
):
from itertools import cycle, islice
def repeat_list_3(values, n):
return list(islice(cycle(values), n))
我不知道這是否有效,但你可以這樣做。
l = [0, 1, 2, 3, 4]
N = 12
k = (l * (N // len(l) + len(l) - N % len(l)))[:N]
print(k)
# [0, 1, 2, 3, 4, 0, 1, 2, 3, 4, 0, 1]
首先,您將列表擴展到N + k
個術語,其中N + k
是len(l)
的因子。 最后對結果列表進行切片以獲得N
個元素。
numpy 有一個方便的 function:
np.resize(values, n)
但您需要將其從np.ndarray
轉換回list
我已經使用 zip() 在循環遍歷列表時定義了一個限制。
使用 itertools 的示例:
from itertools import cycle
values = ['a', 'b', 'c', 1]
n = 10
pool = cycle(values)
for item, limit in zip(pool, range(n)):
print(item)
在不導入的情況下執行此操作的一種方法是在不使用 itertools 的情況下循環迭代,這可以使用生成器輕松完成。
values = ['a', 'b', 'c', 1]
def circular():
while True:
for connection in values:
yield connection
n = 10
for item, limit in zip(circular(), range(n)):
print(item)
然而,我確實認為這個解決方案很笨重,並且不使用 zip() ,因為它打算使用。
我還從您的第二個示例中獲取了代碼,並用生成器替換了循環,以避免導入任何內容。
values = ['a', 'b', 'c', 1]
n = 10
def circular():
while True:
for connection in values:
yield connection
def repeat_list_2(values, n):
values_cycler = circular()
repeated = [next(values_cycler) for _ in range(n)]
return repeated
print(repeat_list_2(values, n))
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.