簡體   English   中英

如何在沒有列表切片的情況下按 n 個元素對 python 中的元素進行分組?

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM