2013-02-26 1 views
9

int. Quindi, ho x=[(12,), (1,), (3,)] (elenco di tuple) e voglio x=[12, 1, 3] (elenco di interi) nel miglior modo possibile? Puoi per favore aiutare?Elenco Python di tuple all'elenco di

+3

Modifica la domanda per includere il tentativo di soluzione. Grazie. – bernie

+0

le tue tuple sono sempre della stessa forma? '(n,)'? –

+1

Un'alternativa 'zip (* x) [0]' o 'successiva (zip (* x))' su Py3k – JBernardo

risposta

5
y = [i[0] for i in x] 

Questo funziona solo per un elemento per tupla, però.

Tuttavia, se si dispone di più elementi per tuple, è possibile utilizzare un elenco un po 'più complessa la comprensione:

y = [i[j] for i in x for j in range(len(i))] 

Riferimento: List Comprehensions

+1

@pedro - Sì, avrà sempre un elemento. – NullException

+0

Per il secondo: se hai bisogno di appiattire qualsiasi sequenza di sequenze, c'è una ricetta nei documenti ['itertools'] (http://docs.python.org/2/library/itertools.html#recipes) chiamati' flatten'. Probabilmente vale la pena comprenderlo e la comprensione della lista. – abarnert

+1

Non dovresti invertire l'ordine di 'for's? – phant0m

2

solo fare questo:

x = [i[0] for i in x] 

Spiegazione :

>>> x=[(12,), (1,), (3,)] 

>>> x 
[(12,), (1,), (3,)] 

>>> [i for i in x] 
[(12,), (1,), (3,)] 

>>> [i[0] for i in x] 
[12, 1, 3] 
1

Questo è il modo più efficace:

x = [i for i, in x] 

o, equivalentemente

x = [i for (i,) in x] 

Questo è un po 'più lento:

x = [i[0] for i in x] 
+0

Sei sicuro della differenza di efficienza? In un rapido test con un 'lista' di elementi 1M in 3.3.0, hanno preso rispettivamente 4.15ms e 4.14ms - e sembra che più di 4ms di quello sia stato il tempo impiegato per iterare la lista e costruire un nuovo elenco, quindi niente è probabile che sia più veloce. Se si cambia x in un genexp e si sostituiscono i due listcomp con un genexp alimentato a 'deque (genexp, maxlen = 0)', ottengo 1.36us contro 1.32us. – abarnert

+0

Ancora più importante, quale scenario stai immaginando dove qualcuno si preoccuperebbe quale di questi due è più efficiente? – abarnert

+1

Dov'è questa tendenza di efficienza per Python su SO proveniente comunque? Per me, sembra un trucco guadagnare più punti. – phant0m

0

è possibile utilizzare la funzione mappa ....

map(lambda y: y[0], x) 
+2

Se vuoi usare 'map', puoi usare' itemgetter' invece di 'lambda'. – abarnert

11

Non hai detto cosa intendi per "migliore", ma presumibilmente vuoi dire "più pithonic" o "più leggibile" o qualcosa del genere.

La comprensione dell'elenco fornita da F3AR3DLEGEND è probabilmente la più semplice. Chiunque sappia leggere una lista di comprensione, saprà immediatamente cosa significa.

y = [i[0] for i in x] 

Tuttavia, spesso non è necessario un elenco, solo qualcosa che può essere ripetuto una volta. Se hai un miliardo di elementi in x, costruire un miliardesimo elemento solo per iterarlo su di esso un elemento alla volta può essere una cattiva idea. Quindi, è possibile utilizzare un generatore di espressione:

y = (i[0] for i in x) 

Se si preferisce la programmazione funzionale, si potrebbe preferire di usare map. L'aspetto negativo di map è che si deve passare una funzione, non solo espressione, il che significa che sia necessario utilizzare una funzione lambda, o itemgetter:

y = map(operator.itemgetter(0), x) 

In Python 3, questo è equivalente al generatore espressione; se si desidera un list, passarlo a list. In Python 2, restituisce uno list; se si desidera un iteratore, utilizzare itertools.imap anziché map.

Se si desidera una soluzione appiattimento più generico, è possibile scrivere uno voi stessi, ma è sempre la pena di guardare itertools di soluzioni generiche di questo tipo, e non v'è infatti una ricetta chiamata flatten che viene utilizzato per "appiattire un livello di nesting".Quindi, copiare e incollare che nel codice (o pip install more-itertools) e si può solo fare questo:

y = flatten(x) 

Se si guarda a come flatten è implementato, e poi a come chain.from_iterable è implementato, e poi a come chain è implementato, noterai che potresti scrivere la stessa cosa in termini di builtin. Ma perché preoccuparsi, quando flatten sarà più leggibile ed evidente?

Infine, se si vuole ridurre la versione generica a un elenco di comprensione nidificato (o generatore di espressione, ovviamente):

y = [j for i in x for j in i] 

Tuttavia, list comprehension annidati sono molto facili da sbagliare, sia in forma scritta e leggere. (Nota che F3AR3DLEGEND, la stessa persona che per prima ha dato la risposta più semplice, ha anche dato una comprensione annidata e ha sbagliato. Se non riesce a tirarlo fuori, sei sicuro di voler provare?) Per casi davvero semplici, loro non troppo male, ma ancora, penso che flatten sia molto più facile da leggere.

+0

Allora, qual è la tua opinione sulla tuple disimballaggio alla corrispondenza del modello? –

+0

@PavelAnossov: che ne pensi? Quando si desidera decomprimere una tupla in variabili denominate separate, è ovviamente esattamente la cosa giusta. Quando hai una tupla di una che vuoi trasformare in un singolo valore, non sembra abbastanza chiara, ma non è davvero discutibile. – abarnert

Problemi correlati