2012-04-08 11 views
10

quiero expandir una listamanera más pequeño para expandir una lista de n

[1,2,3,4] 

por n

por ejemplo para n = 2:

[1,1,2,2,3,3,4,4] 

Estoy buscando la manera más mínima posible de lograr esto sin necesidad de bibliotecas adicionales. Es fácil hacer un ciclo y anexar cada elemento n veces a una nueva lista ... ¿pero hay otra forma?

+0

es 'itertools' permitido? – jamylak

+0

@jamylak '' itertools'' está en la biblioteca estándar, por lo que no usarlo sería una tontería. –

+0

Además, ¿cómo desea que actúe? En este caso, son objetos inmutables, pero ¿cómo debería actuar en objetos mutables? –

Respuesta

13
>>> l = [1,2,3,4] 
>>> [it for it in l for _ in range(2)] 
[1, 1, 2, 2, 3, 3, 4, 4] 
+2

Aquí hay una advertencia para objetos mutables. Si dejas que l sea igual a '' [1, 2, [3]] '' entonces sigue tu método, entonces haz '' test2 [4] .append (4) '' obtendrás '' [1, 1, 2, 2, [3, 4], [3, 4]] ''. Obviamente, esto no será un problema en la mayoría de los casos, pero vale la pena señalarlo. –

+0

Funcionará en Python 2.xy 3.x; el problema es que simplemente tiene dos referencias al mismo elemento, por lo que cuando actualice alguno de ellos, el otro también se actualizará. –

5

itertools[docs] al rescate:

expanded = list(chain(*izip(*tee(l, n)))) 
+2

Whoa. Tanto como me gusta 'itertools', esto me está dando un dolor de cabeza :) –

+0

¿Qué tiene esto que ver con' itertools'? – jamylak

+0

@TimPietzcker Encontré esto más fácil de leer que la respuesta de hamstergene. – Marcin

2
>>> from itertools import chain, tee 
>>> x = [1, 2, 3, 4] 
>>> n = 2 
>>> list(chain.from_iterable(zip(*tee(x, n)))) 
[1, 1, 2, 2, 3, 3, 4, 4] 
+1

¿Por qué replicó otra respuesta? – Marcin

+0

Solo vi su versión anterior como dije en los comentarios, pensé en esto yo mismo. Eliminarlo si lo desea. – jamylak

+2

@Marcin Y él proporcionó importaciones adecuadas ... –

2
sum([[x]*2 for x in l],[]) 

donde l es su lista de

+0

Entonces, para repetir los elementos tres veces, tengo que escribir 'suma ([[x, x, x] para x en l], [])'? Esto parece menos conveniente. –

+1

O puede cambiarse a: 'sum ([[x] * 3 para x en l], [])' – jamylak

+0

@FelixKling: vea el comentario de jamylak sobre lo que dejé implícito en mi respuesta. Aunque supongo que como el OP quería 'n' y no 2, creo que cambiaré eso de' [x, x] '. – ninjagecko

4

hice nota de esto en los comentarios, pero es más fácil de explicar en una respuesta entonces puedo dar ejemplos de código completo. Tenga en cuenta que esto es más una respuesta complementaria a los demás, en lugar de uno completo por derecho propio. Es simplemente una modificación para un caso específico.

Si necesita hacer esto con los objetos mutables, que con un obstáculo utilizando los otros métodos que se presentan aquí:

>>> l = [1,2,3,[4]] 
>>> test = [it for it in l for _ in range(2)] 
>>> test 
[1, 1, 2, 2, 3, 3, [4], [4]] 
>>> test[6].append(5) 
>>> test 
[1, 1, 2, 2, 3, 3, [4, 5], [4, 5]] 

Como tal, es necesario utilizar copy.deepcopy() si se quiere evitar este comportamiento.

>>> import copy 
>>> l = [1,2,3,[4]] 
>>> test = [copy.deepcopy(it) for it in l for _ in range(2)] 
>>> test 
[1, 1, 2, 2, 3, 3, [4], [4]] 
>>> test[6].append(5) 
>>> test 
[1, 1, 2, 2, 3, 3, [4, 5], [4]] 

Naturalmente, esto sólo es necesario para los objetos mutables en una lista, y sólo si se puede esperar que cambien después de crear la nueva lista.

0

Dado que el autor de las respuestas de la pregunta en el comentario de que por "el camino más pequeño posible", quiere decir la longitud mínima del código, me atrevo a publicar la siguiente solución:

>>> sorted([1,2,3,4]*2) 
[1, 1, 2, 2, 3, 3, 4, 4] 

longitud de Es 19 .

0
>>> from itertools import repeat, chain 
>>> seq = [1, 2, 3, 4] 
>>> list(chain.from_iterable(repeat(x, 2) for x in seq)) 
[1, 1, 2, 2, 3, 3, 4, 4] 
0
>>> from itertools import chain 
>>> seq = [1, 2, 3, 4] 
>>> list(chain.from_iterable(zip(*[seq]*2))) 
[1, 1, 2, 2, 3, 3, 4, 4] 
>>> list(chain.from_iterable(zip(*[seq]*6))) 
[1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 2, 3, 3, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4] 
Cuestiones relacionadas