[英]How to group elements in python by n elements without list slicing?
>>> theList = list(range(10))
>>> N = 3
>>> subList = [theList[n:n+N] for n in range(0, len(theList), N)]
>>> subList
[[0, 1, 2], [3, 4, 5], [6, 7, 8], [9]]
如果沒有列表切片,我將如何做到這一點?
使用模運算符%
。
def split_by_n(n, lst):
final = []
sublist = []
for i in range(0, len(lst)):
if i % n != 0: # if i/n has no remainders
sublist.append(lst[i])
elif i != 0: # Reached the end of a sublist. Append to parent and reset.
final.append(sublist)
sublist = []
sublist.append(lst[i])
else: # 0 mod n is 0, so just make sure to add it anyways
sublist.append(lst[i])
final.append(sublist)
return final
有幾種方法:
您可以使用嵌套列表理解與列表中的索引:
(盡管索引的廣泛使用是非 Pythonic 的)
theList = list(range(10))
N = 3
L = len(theList)
subList = [ [theList[j] for j in range(i,min(i+N,L))] for i in range(0,L,N) ]
print(subList)
[[0, 1, 2], [3, 4, 5], [6, 7, 8], [9]]
您也可以使用 itertools.group 通過對分組鍵使用迭代器來實現,或者對每個子范圍使用 itertools.islice( ,N) :
from itertools import groupby
group = iter(range(len(theList)))
subList = [ list(g) for _,g in groupby(theList,key=lambda _:next(group)//N) ]
print(subList)
[[0, 1, 2], [3, 4, 5], [6, 7, 8], [9]]
from itertools import islice
iList = iter(theList)
subList = [ list(islice(iList,N)) for _ in range(0,len(theList),N) ]
print(subList)
[[0, 1, 2], [3, 4, 5], [6, 7, 8], [9]]
如果你不能使用庫,你可以使用 zip() 在列表理解中獲取迭代器的塊:
iList = iter(theList)
subList = [[n for _,n in zip(range(N),iList)] for _ in range(0,len(theList),N)]
print(subList)
[[0, 1, 2], [3, 4, 5], [6, 7, 8], [9]]
或者使用 next() 函數映射:
iList = iter(theList)
subList = [ [f, *map(next,[iList]*(N-1))] for f in iList ]
print(subList)
[[0, 1, 2], [3, 4, 5], [6, 7, 8], [9]]
當然,總是有很好的舊 for 循環方法:
subList = [[]]
for n in theList:
L,V = (subList[-1],n) if len(subList[-1])<N else (subList,[n])
L.append(V)
print(subList)
[[0, 1, 2], [3, 4, 5], [6, 7, 8], [9]]
這是使用 itertools 的(可能是過度殺傷)解決方案:
步驟 1. 將theList
轉換為生成器:
gList = (x for x in theList)
步驟 2. itertools.islice
生成 N 組(永遠):
import itertools as it
z1 = list(it.islice(gList,N)) # [0,1,2]
z2 = list(it.islice(gList,N)) # [3,4,5]
z3 = list(it.islice(gList,N)) # [6,7,8]
z4 = list(it.islice(gList,N)) # [9]
z5 = list(it.islice(gList,N)) # [], etc.
(請注意,我們需要在此之后重置gList
。)
步驟 3. 將其包裝在另一個生成器中並使用itertools.takewhile
:
import itertools as it
gList = (x for x in theList)
subList = list(it.takewhile(lambda y: len(y) > 0,
(list(it.islice(gList,N)) for _ in it.count(1))))
這里it.count(1)
就像一個while True:
循環
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.