Mai mult
Cum vă împărțiți lista în mod uniform bucăți de dimensiuni?
Am o listă de lungime arbitrară, și trebuie să-l împărțim în bucăți de dimensiuni egale și opera. Există unele moduri evidente de a face acest lucru, ca și cum ai ține un contor și două liste, și atunci când cea de-a doua listă se umple, adăugați-l la prima listă și gol de-a doua listă pentru următoarea rundă de date, dar acest lucru poate fi extrem de costisitoare.
Mă întrebam dacă cineva ar fi o soluție bună pentru această pentru liste de orice lungime, de exemplu, folosind generatoare.
Am fost în căutarea pentru ceva util în itertools` dar nu puteam't găsi nimic în mod evident utile. S-ar putea'am ratat-o, totuși.
Intrebare legate de: ceea Ce este cel mai "pythonic" mod de a repeta peste o listă în bucăți?
2047
60
Aici's un generator care produce bucăți vrei:
Daca're folosind Python 2, ar trebui să utilizați
xrange () "în loc de" range()
:De asemenea, puteți folosi pur și simplu lista de înțelegere în loc de a scrie o funcție, deși l's o idee bună pentru a îngloba astfel de operațiuni în nume de funcții, astfel încât codul este mai ușor de înțeles. Python 3:
Python 2 versiune:
Daca vrei ceva super simplu:
Folosesc gama () "în loc de" xrange()` în cazul Python 3.x
Direct de la (vechi) Python documentare (retete pentru itertools):
Versiunea actuală, cum a sugerat de către J. F. Sebastian:
Cred că Guido's time machine funcționează—lucrat—va locul de muncă—va fi lucrat—a fost din nou de lucru.
Aceste soluții de lucru pentru că
[iter(iterable)]*n
(sau echivalentul în versiunea anterioară) creează o iterator, repetate de " n "ori în listă.izip_longest
apoi efectuează în mod eficient un round-robin de "fiecare" iterator; pentru că aceasta este aceeași iterator, este avansat de către fiecare astfel de apel, care rezultă în fiecare astfel de zip-roundrobin generând un tuplu din" n " elemente.Știu că acest lucru este la fel de vechi, dar nimeni nu a menționat încă
numpy.array_split
:Am'm-a surprins nimeni nu a crezut de a folosi iter's doi-argument forma:
Demo:
Aceasta funcționează cu orice iterable și produce ieșire alene. Se întoarce tupluri, mai degrabă decât iteratori, dar cred că are o anumită eleganță cu toate acestea. De asemenea, nu't pad; dacă vrei umplutură, o simplă variație pe cele de mai sus va fi suficient:
Demo:
Ca
izip_longest
bazate pe soluții, mai sus always tampoane. După câte știu eu, nu's nu una sau două linii itertools reteta pentru o funcție care optionally tampoane. Prin combinarea celor două abordări de mai sus, acesta vine destul de aproape:Demo:
Cred că acest lucru este cel mai scurt chunker propuse, care oferă opțional umplutură.
Ca Tomasz Gandor observedcele două umplutură chunkers va opri în mod neașteptat dacă vor întâlni o secvență lungă de pad valori. Aici's o ultimă variantă care funcționează în jurul valorii de această problemă într-un mod rezonabil:
Demo:
Aici este un generator care funcționează pe arbitrare iterables:
Exemplu:
Simplu, dar elegant
sau, dacă preferați:
Am văzut cel mai minunat Python-ish răspuns într-un duplicat de la această întrebare:
Puteți crea n-tuplu pentru orice n. Dacă o = range(1, 15), atunci rezultatul va fi:
Dacă lista este împărțită în mod egal, atunci puteți înlocui
zip_longest cu "zip", în caz contrar triplet
(13, 14, Niciuna)ar fi pierdut. Python 3 este utilizat de mai sus. Pentru Python 2, folosesc izip_longest
.Critica de alte raspunsuri aici:
Nici unul dintre aceste răspunsuri sunt uniform bucăți de dimensiuni, toate acestea lasă un runt bucată la sfârșitul anului, astfel încât acestea're nu este complet echilibrat. Dacă ați fost utilizați aceste funcții pentru a distribui munca, ai've built-in perspectiva un susceptibile de finisare bine în fața celorlalți, așa că ar sta în jurul valorii de a nu face nimic în timp ce alții au continuat să lucreze din greu.
De exemplu, actualul top răspuns se termină cu:
Nu-mi place că runt la sfârșitul!
Altele, cum ar fi lista(grouper(3, xrange(7)))", și " bucată(xrange(7), 3)
întoarce amândoi:
[(0, 1, 2), (3, 4, 5), (6, Nici unul, Nici una)]`. "Nici unul" 's sunt doar de umplutură, și destul de elegant, în opinia mea. Ele NU sunt uniform chunking la iterables.De ce't vom împărți aceste mai bine?
Soluția mea(s)
Aici's o soluție echilibrată, adaptată la o funcție I've utilizate în producție (a se reține în Python 3 pentru a înlocui `xrange cu "range"):
Și am creat un generator care face acelasi lucru, dacă l-ai pus într-o listă:
Și, în sfârșit, când am văzut că toate funcțiile de mai sus se întoarcă elemente într-un învecinate ordine (ca s-au dat):
Ieșire
Pentru a le testa:
Care imprimă:
Observați că învecinate generator oferi în bucăți de aceeași lungime modele ca celelalte două, dar elementele sunt toate în ordine, și ei sunt la fel de uniform împărțită după cum se poate împărți o listă de elemente discrete.
Dacă știți dimensiunea listei:
Dacă tu nu't (un iterator):
În acest din urmă caz, acesta poate fi reformulat într-un mod mai frumos dacă puteți fi sigur că secvența conține întotdeauna un număr întreg de bucăți de dimensiune dată (de exemplu, nu există nici incomplete ultima bucată).
Dacă ai avut o dimensiune bucată de 3 de exemplu, ai putea face:
sursa: http://code.activestate.com/recipes/303060-group-a-list-into-sequential-n-tuples/
Mi-ar folosi acest lucru atunci când mi bucată dimensiune este număr fix nu pot tip, de exemplu '3', și nu se va schimba niciodată.
De toolz biblioteca are `partiție funcția pentru acest lucru:
Îmi place Python doc's version propus de tzot și J. F. Sebastian o mulțime, dar are două neajunsuri:
Am'm, folosind o mulțime în codul meu:
UPDATE: UN leneș bucăți versiune:
cod:
rezultatul:
Am fost curios cu privire la performanța de abordări diferite și aici este:
Testat pe Python 3.5.1
Rezultate:
La acest moment, cred că avem nevoie de un recursiv generator, doar în cazul în...
În python 2:
În python 3:
De asemenea, în caz de invazie Extraterestră masiv, un decorat recursiv generator ar putea deveni la îndemână:
De asemenea, puteți utiliza
get_chunks
funcția deutilspie
biblioteca fi:Puteți instala
utilspie
prin pip:Disclaimer: eu sunt creatorul utilspie biblioteca.
Unde AA este matrice, SS este de dimensiune bucată. De exemplu:
heh, o versiune linie de