Jak najlepiej podzielić listę na mniej więcej równe części? Na przykład, jeśli lista ma 7 elementów i jest podzielona na 2 części, chcemy uzyskać 3 elementy w jednej części, a druga powinna mieć 4 elementy.
Szukam czegoś takiego, even_split(L, n)
co rozpada się L
na n
części.
def chunks(L, n):
""" Yield successive n-sized chunks from L.
"""
for i in range(0, len(L), n):
yield L[i:i+n]
Powyższy kod daje porcje po 3 zamiast 3 porcji. Mógłbym po prostu transponować (powtórzyć to i pobrać pierwszy element z każdej kolumny, wywołać tę część pierwszą, a następnie wziąć drugą i umieścić ją w części drugiej itd.), Ale to niszczy kolejność elementów.
>>> chunkIt(range(8), 6)
=>[[0], [1], [2, 3], [4], [5], [6], [7]]
chunkIt(range(10), 9)
powinien zwrócić 9 części, ale tak nie jest.Możesz napisać to po prostu jako generator list:
Przykład:
źródło
n = min(n, len(a)) # don't create empty buckets
na linii 1, aby uniknąć tworzenia pustych wiader w scenariuszach jaklist(split(range(X, Y)))
gdzieX < Y
To jest raison d'être dla
numpy.array_split
*:* kredyt dla Zero Piraeus w pokoju 6
źródło
*
wprint
za?print(L)
i `print (* L). Zobacz także stackoverflow.com/a/36908/2184122 lub wyszukaj „użycie gwiazdki w pythonie”.O ile nie chcesz niczego głupiego, takiego jak ciągłe fragmenty:
źródło
zip(*chunkify(range(13), 3))
wyniki w[(0, 1, 2), (3, 4, 5), (6, 7, 8), (9, 10, 11)]
Zmiana kodu w celu uzyskania
n
porcji zamiast fragmentówn
:co daje:
Spowoduje to przypisanie dodatkowych elementów do ostatniej grupy, która nie jest idealna, ale dobrze mieści się w twojej specyfikacji "z grubsza N równych części" :-) Przez to rozumiem, że 56 elementów byłoby lepsze jako (19,19,18), podczas gdy to daje (18, 18, 20).
Możesz uzyskać bardziej zbalansowane dane wyjściowe za pomocą następującego kodu:
które wyjścia:
źródło
for x in chunks(mylist,num): print x
, otrzymuję pożądane fragmenty, ale między nimi pojawia się pusta lista. Masz jakiś pomysł, dlaczego? To znaczy, dostaję dużo[]
, jeden po każdym kawałku.Jeśli podzielisz
n
elementy na z grubszak
kawałki, możesz zwiększyć je on % k
jeden element od innych, aby rozdzielić dodatkowe elementy.Poniższy kod poda długość fragmentów:
Przykład:
n=11, k=3
wyniki[4, 4, 3]
Następnie możesz łatwo obliczyć indeks początkowy dla porcji:
Przykład:
n=11, k=3
wyniki[0, 4, 8]
Używając
i+1
th kawałka jako granicy, otrzymujemy, żei
th fragment listyl
z lenn
jestNa koniec utwórz listę ze wszystkich fragmentów, używając funkcji rozumienia list:
Przykład:
n=11, k=3, l=range(n)
wyniki[range(0, 4), range(4, 8), range(8, 11)]
źródło
Spowoduje to podział według jednego wyrażenia:
Lista w tym przykładzie ma rozmiar 18 i jest podzielona na 5 części. Rozmiar części różni się nie więcej niż jednym elementem.
źródło
Zobacz
more_itertools.divide
:Zainstaluj przez
> pip install more_itertools
.źródło
Oto jeden, który dodaje,
None
aby listy były równej długościźródło
Oto moje rozwiązanie:
Produkuje
źródło
Oto generator, który może obsłużyć dowolną dodatnią (całkowitą) liczbę fragmentów. Jeśli liczba porcji jest większa niż długość listy wejściowej, niektóre porcje będą puste. Ten algorytm przełącza się między krótkimi i długimi kawałkami, zamiast je segregować.
Dołączyłem również kod do testowania
ragged_chunks
funkcji.Możemy uczynić to nieco bardziej wydajnym, eksportując mnożenie do
range
wywołania, ale myślę, że poprzednia wersja jest bardziej czytelna (i bardziej SUCHA).źródło
Spójrz na numpy.split :
źródło
Implementacja metodą numpy.linspace.
Po prostu określ liczbę części, na które chcesz podzielić tablicę. Podziały będą prawie równej wielkości.
Przykład:
Daje:
źródło
Moje rozwiązanie, łatwe do zrozumienia
I najkrótsza jedna linijka na tej stronie (napisana przez moją dziewczynę)
źródło
Korzystanie ze rozumienia list:
źródło
Innym sposobem byłoby coś takiego, chodzi o to, aby użyć groupera, ale się go pozbyć
None
. W tym przypadku będziemy mieć wszystkie „małe_części” utworzone z elementów w pierwszej części listy i „większe_części” z dalszej części listy. Długość „większych części” wynosi len (small_parts) + 1. Musimy rozważyć x jako dwie różne części składowe.Sposób, w jaki to skonfigurowałem, zwraca listę krotek:
źródło
Oto inny wariant, który rozkłada „pozostałe” elementy równomiernie na wszystkie fragmenty, jeden po drugim, aż ich nie ma. W tej implementacji większe fragmenty pojawiają się na początku procesu.
Na przykład wygeneruj 4 fragmenty z listy 14 elementów:
źródło
To samo, co odpowiedź zadania , ale uwzględnia listy o rozmiarze mniejszym niż liczba fragmentów.
jeśli n (liczba fragmentów) wynosi 7, a lst (lista do podziału) to [1, 2, 3], fragmenty to [[0], [1], [2]] zamiast [[0], [1] ], [2], [], [], [], []]
źródło
Możesz również użyć:
źródło
Przykład:
l = [a for a in range(97)]
powinien składać się z 10 części, z których każda ma 9 elementów oprócz ostatniej.Wynik:
źródło
Powiedzmy, że chcesz podzielić listę [1, 2, 3, 4, 5, 6, 7, 8] na 3 listy elementów
np. [[1,2,3], [4, 5, 6], [7, 8]] , gdzie jeśli ostatnie pozostałe elementy są mniejsze niż 3, są zgrupowane razem.
Produkcja: [[1, 2, 3], [4, 5, 6], [7, 8]]
Gdzie długość jednej części wynosi 3. Zastąp 3 własnym rozmiarem porcji.
źródło
1>
2>
źródło
oto moja wersja (zainspirowana Maxem)
źródło
Zaokrąglenie przestrzeni linkowej i użycie jej jako indeksu jest łatwiejszym rozwiązaniem niż to, co proponuje amit12690.
źródło
Wybrałem z tego linku i to mi pomogło. Miałem predefiniowaną listę.
źródło
powiedz, że chcesz podzielić na 5 części:
źródło
Sam napisałem kod w tym przypadku:
divide_ports (1, 10, 9) zwróci
źródło
ten kod działa dla mnie (zgodny z Python3):
przykład (dla typu bytearray , ale działa również dla list s):
źródło
Ten zapewnia fragmenty o długości <= n,> = 0
pok
na przykład
źródło
Wypróbowałem większość rozwiązań, ale nie działały one w moim przypadku, więc tworzę nową funkcję, która działa w większości przypadków i dla dowolnego typu tablicy:
źródło