2010-03-15 16 views
19

Quiero escribir una función que reviva una lista [1,5,3,6,...] y da [1,1,5,5,3,3,6,6,...] alguna idea de cómo hacerlo? graciasduplicar cada miembro en una lista - python

+2

Sonidos a la orden del día. Hay mejores formas de trabajar con una lista que duplicar los elementos. –

Respuesta

12
>>> a = [1, 2, 3] 
>>> b = [] 
>>> for i in a: 
    b.extend([i, i]) 


>>> b 
[1, 1, 2, 2, 3, 3] 

o

>>> [a[i//2] for i in range(len(a)*2)] 
[1, 1, 2, 2, 3, 3] 
+0

Debería usar '//' para la división del piso en Python 2, también. –

+0

@Mike: seguro que tienes razón, excepto por supuesto en la división '/' asegura que 'int' sea devuelto. – SilentGhost

38
>>> a = range(10) 
>>> [val for val in a for _ in (0, 1)] 
[0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9] 

N. B. _ se usa tradicionalmente como un nombre de variable de marcador de posición en el que no desea hacer nada con el contenido de la variable. En este caso, solo se usa para generar dos valores para cada vuelta del ciclo externo.

Para convertir esto de una lista en un generador, reemplace los corchetes por corchetes.

+1

'_' es, en estos días, utilizado para i18n/l10n (google). Todavía tiendo a usarlo * si * Sé que no habrá un i18n en este módulo. Else I (usaría) '__' (dos guiones bajos). –

1

usaría

import itertools 
foo = [1, 5, 3, 6] 
new = itertools.chain.from_iterable([item, item] for item in foo) 

new habrá un iterador que perezosamente itera sobre los elementos duplicados. Si necesita la lista real calculada, puede hacer list(new) o utilizar una de las otras soluciones.

+1

o más corto: 'itertools.chain.from_iterable (itertools.izip (foo, foo))' –

+0

Consideré ese código que es más corto pero no me pareció más claro. –

6

Si ya tiene la receta roundrobin se describe en la documentación de itertools -y que queda muy cerca, a continuación, puedes utilizar

roundrobin(my_list, my_list) 
+0

+1, esta es una buena manera de lograr esto. –

1

Por mucho que Guido no le gustan los operadores funcionales, que pueden ser bastante zurcido útil:

>>> from operator import add 
>>> a = range(10) 
>>> b = reduce(add, [(x,x) for x in a]) 
+0

En el caso de reducir, a menudo significa increíblemente lento. Es importante medir lo que 'reduce 'está haciendo. A menudo, es impactante cuánto cómputo reduce las fuerzas. –

+0

Hice un script de prueba con cada uno de los métodos en esta página con el baselist = range (10) y 1,000,000 de iteraciones. El más lento tomó 5.094 segundos y el más rápido tardó 3.622 segundos. Mi ejemplo de reducción tomó 3.906 segundos. –

+1

'rango (10)' es muy pequeño, por lo que la complejidad tiene un rol pequeño. Esta solución es cuadrática. todos los otros que veo aquí son lineales. Además, algunos de los otros me parecen más legibles. –

8

me gustaría utilizar zip y itertools.chain.

>>> import itertools 
>>> l = [1,5,3,6,16] 
>>> list(itertools.chain(*zip(l,l))) 
[1, 1, 5, 5, 3, 3, 6, 6, 16, 16] 

Nota: sólo se utiliza list consumir el generador para que se ajuste para imprimir. Probablemente no necesite la llamada list en su código ...

1

Es posible la multiplicación de la lista de uso. Si necesita que cada miembro de la lista solo use el método ordenado.

>>> lst = [1,2,3,4] 
>>> sorted(lst*2) 
[1,1,2,2,3,3,4,4] 
+0

¿Qué tal si quieres mantener el orden de la lista original? ¿Qué pasa si los artículos de la lista no son pedidos? – Moberg

Cuestiones relacionadas