2011-08-18 7 views
5

Così ho una serie della seguente forma:Perché non riesco a ottenere due elenchi da una sola comprensione di lista?

[(1, u'first_type', u'data_gid_1'), 
(2, u'first_type', u'data_gid_2'), 
(3, u'first_type', u'data_gid_3'), 
(4, u'first_type', u'data_gid_4')] 

Ora voglio per estrarre il primo e l'ultimo elemento di ogni elenco all'interno in elenchi separati. Quindi se lo faccio:

>>> ids = [dat[0] for dat in all_data] 
>>> gds = [dat[2] for dat in all_data] 

Questo funziona come mi aspetto. Tuttavia Stavo cercando di unire questi due in una sola chiamata, qualcosa di simile:

(ids, gds) = [(dat[0], dat[2]) for dat in all_data] 

Questo però non riesce con un: ValueError: too many values to unpack

Così qualcuno potrebbe spiegare perché questo sta accadendo e se quello che sto cercando di fare è persino possibile.

saluti, Bogdan

+1

C'è qualcosa di sbagliato nel lasciarlo come due linee? Voglio dire, a volte è bello essere chiari. –

+1

Niente di male, questa è ancora la soluzione che sto usando, volevo solo capire perché stavo ottenendo l'errore per usi futuri. – Bogdan

+0

@Bogdan Questo è veramente onorevole. Ti darei un +1 per quel commento. – cwallenpoole

risposta

8

Non funziona perché la lunghezza [(dat[0], dat[2]) for dat in all_data] è uguale alla lunghezza di all_data, che non è la stessa lunghezza della tupla (ids, gds).

Prova a modificare:

(ids, gds) = zip(*[(dat[0], dat[2]) for dat in all_data]) 

o ancora più breve:

(ids, gds) = zip(*all_data)[::2] 

Come osservato in un'altra risposta, ids e gds sarà ora tuple, quindi se avete bisogno liste, fare così:

(ids, gds) = map(list, zip(*all_data)[::2]) 



Il zip(*something) è un idioma piuttosto frequente in python. Se si guarda a una lista di liste come matrice, cioè

l = [[1, 2, 3], 
    [4, 5, 6]] 

Poi zip(*l) traspone quella matrice:

zip(*l) == [(1, 4), 
      (2, 5), 
      (3, 6)] 

I * funziona così: some_func(*some_list)spacchettasome_list in modo che la funzione è in effetto chiamato con gli elementi di some_list come argomenti. Quindi zip(*l) corrisponde a zip([1, 2, 3], [4, 5, 6]). Here's la parte pertinente del tutorial python.

zip agisce come un zipper, da cui il nome, quindi restituisce una lista con questi elementi: una tupla di tutti i primi elementi degli argomenti dati, seguita da una tupla di tutti i secondi elementi, ecc

+1

Bello. Anche se una spiegazione leggermente migliore per aiutare l'OP: "'Troppi valori per scompattare' si verifica perché stai tentando di assegnare un elenco di 4 elementi a una tupla di 2 elementi." +1. –

+0

Grazie per gli input. Sono entrato adesso. – Bogdan

+0

Il significato era chiedere esattamente che cosa fa zip(). Grazie per il chiarimento. Accetterà non appena scade il tempo. – Bogdan

1

[(dat[0], dat[2]) for dat in all_data] significa che stai creando un elenco di tuple (dat[0],dat[2]). Ciò non significa che tu abbia due elenchi, uno di d[0] e l'altro di d[2].

Si potrebbe semplicemente utilizzare zip, ma ciò comporterà tuple.Se si desidera che le liste, si dovrà applicare list al risultato:

(ids, gds) = map(list,zip(*[(dat[0], dat[2]) for dat in a])) 
4

codice qui sotto sarà anche fare il trucco:

data = [(1, u'first_type', u'data_gid_1'), 
(2, u'first_type', u'data_gid_2'), 
(3, u'first_type', u'data_gid_3'), 
(4, u'first_type', u'data_gid_4')] 

ids, gds = ([row[i] for row in data] for i in [0,2]) 
0

Dal momento che si sta creando due liste separate, provate questo:

ids, dgs = [(dat[0]) for dat in all_data], [(dat[2]) for dat in all_data] 

o si può scompattarlo in un unico elenco con il comando si è utilizzato:

x = [(dat[0], dat[2]) for dat in all_data] 
Problemi correlati