2012-03-12 65 views
103

Ho una lista python che gira in 1000's. Qualcosa di simile:Dividere una lista python in altre "sottoliste" i.e liste più piccole

data=["I","am","a","python","programmer".....] 

dove, len (dati) = dicono 1003

Vorrei ora per creare un sottoinsieme di questa lista (dati) dividendo la lista originale in blocchi di 100. Quindi, a Alla fine, Id piace avere qualcosa del tipo:

data_chunk1=[.....] #first 100 items of list data 
data_chunk2=[.....] #second 100 items of list data 
. 
. 
. 
data_chunk11=[.....] # remainder of the entries,& its len <=100, len(data_chunk_11)=3 

Esiste un modo pitone per raggiungere questo obiettivo? Ovviamente posso usare i dati [0: 100] e così via, ma presumo che sia terribilmente non-pitonico e molto inefficiente.

Molte grazie.

+3

Si potrebbe utilizzare [funzione array_split di numpy ] (https://docs.scipy.org/doc/numpy/reference/generated/numpy.array_split.html#numpy.array_split) ad es., 'np.array_split (np.array (data), 20)' da dividere in 20 pezzi di dimensioni quasi uguali. Per assicurarti che i blocchi siano esattamente uguali, usa 'np.split'. – AlexG

risposta

200

direi

chunks = [data[x:x+100] for x in xrange(0, len(data), 100)] 

Se si utilizza python 3.x range() sostituisce python 2.x di xrange(), modificando il codice qui sopra per:

chunks = [data[x:x+100] for x in range(0, len(data), 100)] 
+3

con quello potresti essere in grado di farlo in un modo più "pitonico" con itertools, ma sarà brutto come il peccato! –

+6

Se hai una lista e vuoi una lista, non c'è motivo di preoccuparti di itertools. ha senso se vuoi dividere un flusso di dati senza mai creare l'intera cosa – alexis

+3

Utilizzare itertools sarebbe in realtà il modo meno pitioso di farlo, vero? – Pastafarian

6
chunks = [data[100*i:100*(i+1)] for i in range(len(data)/100 + 1)] 

Questo è equivalente alla risposta accettata. Ad esempio, accorciando a lotti di 10 per migliorare la leggibilità:

data = range(35) 
print [data[x:x+10] for x in xrange(0, len(data), 10)] 
print [data[10*i:10*(i+1)] for i in range(len(data)/10 + 1)] 

Uscite:

[[0, 1, 2, 3, 4, 5, 6, 7, 8, 9], [10, 11, 12, 13, 14, 15, 16, 17, 18, 19], [20, 21, 22, 23, 24, 25, 26, 27, 28, 29], [30, 31, 32, 33, 34]] 
[[0, 1, 2, 3, 4, 5, 6, 7, 8, 9], [10, 11, 12, 13, 14, 15, 16, 17, 18, 19], [20, 21, 22, 23, 24, 25, 26, 27, 28, 29], [30, 31, 32, 33, 34]] 
+2

Questo non è quello che viene chiesto. –

+0

In realtà è equivalente, tranne che per un bug in cui manca l'ultimo batch, ora risolto. – qris

24

In realtà penso che usando fette pianura è la soluzione migliore in questo caso:

for i in range(0, len(data), 100): 
    chunk = data[i:i + 100] 
    ... 

Se vuoi evitare di copiare le fette, potresti usare itertools.islice(), ma qui non sembra necessario.

La documentazione itertools() contiene anche la famosa "cernia" modello:

def grouper(n, iterable, fillvalue=None): 
    "grouper(3, 'ABCDEFG', 'x') --> ABC DEF Gxx" 
    args = [iter(iterable)] * n 
    return izip_longest(fillvalue=fillvalue, *args) 

Si avrebbe bisogno di modificarlo per trattare correttamente l'ultimo pezzo, quindi penso che la soluzione straight-forward con fette di pianura è preferibile.

+0

grazie per la risposta. Ho pensato alla tua prima soluzione semplice fetta, ma poi ho pensato che forse è troppo inefficiente e troppo ingenuo da parte mia .. Sono un po 'sorpreso che non ci sia un modo pitonioso (un liner) per raggiungere questo compito :( – JohnJ

Problemi correlati