2013-02-14 7 views
13

Ho un list in Python:elemento duplicato nella lista python

l = ['a', 'c', 'e', 'b'] 

voglio duplicare ogni elemento immediatamente successivo a quello originale.

ll = ['a', 'a', 'c', 'c', 'e', 'e', 'b', 'b'] 

L'ordine degli elementi deve essere conservato.

+1

'lista (itertools.chain.from_iterable ([(el, el) per el in l]))' – tesla1060

+2

@ tesla1060 Bene, funziona, quindi qual è il tuo problema? –

+1

Non riesco a trovare domande simili, perché sono in downvoted? Inoltre, ho persino fornito un modo per commentare, ma vorrei essere sicuro che ci sia un modo più semplice per farlo. – tesla1060

risposta

16
>>> l = ['a', 'c', 'e', 'b'] 
>>> [x for pair in zip(l,l) for x in pair] 
['a', 'a', 'c', 'c', 'e', 'e', 'b', 'b'] 

O

>>> from itertools import repeat 
>>> [x for item in l for x in repeat(item, 2)] 
['a', 'a', 'c', 'c', 'e', 'e', 'b', 'b'] 
+0

Come nota, questo non funzionerà con iterabili arbitrari che possono essere esauriti. –

+1

@Lattyware: true, ma funziona per il problema come descritto. –

+0

In effetti, era solo qualcosa da tenere a mente nel caso qualcuno cercasse di applicarlo in un'altra situazione. –

4
import itertools 

ll = list(itertools.chain.from_iterable((e, e) for e in l)) 

Al lavoro:

>>> import itertools 
>>> l = ['a', 'c', 'e', 'b'] 
>>> ll = list(itertools.chain.from_iterable((e, e) for e in l)) 
>>> ll 
['a', 'a', 'c', 'c', 'e', 'e', 'b', 'b'] 

Come Lattyware sottolineato, nel caso in cui si desidera di più che raddoppiare l'elemento:

from itertools import chain, repeat 

ll = list(chain.from_iterable(repeat(e, 2) for e in l)) 
+1

Per rendere questo un po 'più flessibile 'itertools.repeat()' potrebbe essere una soluzione migliore. –

+1

Penso che tu voglia 'chain.from_iterable' – mgilson

+0

Mi dispiace, ma ho dovuto modificare per liberarmi di quello spazio tra' chain' e la sua lista degli argomenti. Inoltre, risolto usando 'chain.from_iterable()' come suggerito da mgilson. Ho anche aggiunto degli spazi tra gli argomenti come appropriato, e ho cambiato '_' - che di solito è usato per indicare un valore di lancio. –

1

Prova questa

for i in l: 
    ll.append(i) 
    ll.append(i) 

Demo

Sarà solo fare il vostro lavoro ma non è un modo ottimale di fare questo.

utilizzare le ans. postato da @Steven Rumbalski

+0

Questo è un modo relativamente inefficiente di fare ciò. –

+0

@Lattyware Accetto ma questo Ques. non merita più di questo.it non è detto che richiede una soluzione ottimizzata. Voglio solo una soluzione. – Arpit

+0

È un modo pazzesco per guardarlo. Le risposte migliori sono generalmente quantità di codice simili a questo, e vale sempre la pena di fare le cose nel miglior modo possibile, dove non ci vuole uno sforzo extra per farlo. –

1

Ecco un modo piuttosto semplice:

sum(zip(l, l), tuple()) 

duplica ogni elemento, e li aggiunge una tupla. Se non si desidera una tupla (come sospetto), è possibile chiamare list sul tupla:

list(sum(zip(l, l), tuple())) 

Poche altre versioni (che le liste di resa):

list(sum(zip(l, l),())) 

sum([list(i) for i in zip(l, l)], []) 

sum(map(list, zip(l, l)), []) 
+0

Funziona, ma richiede un tempo quadratico. È un'opzione davvero cattiva. – user2357112

6

Questo è vecchio ma non riesco a vedere l'opzione dritto in avanti qui (IMO):

[ item for item in l for repetitions in range(2) ] 

Così, per il caso specifico:

>>> l = ['a', 'c', 'e', 'b'] 
l = ['a', 'c', 'e', 'b'] 
>>> [ i for i in l for r in range(2) ] 
[ i for i in l for r in range(2) ] 
['a', 'a', 'c', 'c', 'e', 'e', 'b', 'b'] 
>>> 

e generalizzando:

[ item for item in l for _ in range(r) ] 

dove r è la quantità di ripetizioni che si desidera.

Quindi questo ha una O (n.r) complessità di tempo e spazio, è breve, senza dipendenze e anche idiomatico.

+0

Funziona anche in Python 3, esattamente quello che stavo cercando :) –