2010-10-10 26 views
19

Cuando tengo que añadir varios artículos idénticos a la lista utilizo lista.extend:lista.extend y comprensión de lista

a = ['a', 'b', 'c'] 
a.extend(['d']*3) 

Resultado

['a', 'b', 'c', 'd', 'd', 'd'] 

Pero, cómo hacer el similar con la lista ¿comprensión?

a = [['a',2], ['b',2], ['c',1]] 
[[x[0]]*x[1] for x in a] 

Resultado

[['a', 'a'], ['b', 'b'], ['c']] 

Pero necesito éste

['a', 'a', 'b', 'b', 'c'] 

¿Alguna idea?

Respuesta

23

LCs apilados.

[y for x in a for y in [x[0]] * x[1]] 
+5

Gracias! Funciona, pero ni siquiera entiendo cómo leer esta expresión. – Stas

+0

'for x in a' extrae cada uno de los elementos de' a' uno a la vez en 'x'. 'for y in ...' crea una nueva lista de' x' y extrae sus elementos de a uno en 'y'. Todo sucede al mismo tiempo (más o menos), haciendo que todo esté en el mismo nivel de anidación. –

+9

Por lo general, es más claro al desempacar: [y para (artículo, veces) en a para y en [elemento] * veces] – tokland

4
>>> a = [['a',2], ['b',2], ['c',1]] 
>>> [i for i, n in a for k in range(n)] 
['a', 'a', 'b', 'b', 'c'] 
1
import operator 
a = [['a',2], ['b',2], ['c',1]] 
nums = [[x[0]]*x[1] for x in a] 
nums = reduce(operator.add, nums) 
+2

'reduce (operator.add, ...)' es O (n^2). – kennytm

3

Un enfoque itertools:

import itertools 

def flatten(it): 
    return itertools.chain.from_iterable(it) 

pairs = [['a',2], ['b',2], ['c',1]] 
flatten(itertools.repeat(item, times) for (item, times) in pairs) 
# ['a', 'a', 'b', 'b', 'c'] 
1
>>> a = [['a',2], ['b',2], ['c',1]] 
>>> sum([[item]*count for item,count in a],[]) 
['a', 'a', 'b', 'b', 'c'] 
2

Si prefiere extenderse sobre las listas por comprensión:

a = [] 
for x, y in l: 
    a.extend([x]*y)