views:

85

answers:

6

When I need to add several identical items to the list I use list.extend:

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

Result

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

But, how to do the similar with list comprehension?

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

Result

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

But I need this one

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

Any ideas?

+6  A: 

Stacked LCs.

[y for x in a for y in [x[0]] * x[1]]
Ignacio Vazquez-Abrams
Thanks! It works but I don't even understand how to read this expression.
Stas
`for x in a` extracts each of the elements of `a` one at a time into `x`. `for y in ...` creates a new list from `x` and extracts its elements one at a time into `y`. It all happens at the same time (more or less), causing it all to be at the same nesting level.
Ignacio Vazquez-Abrams
It is usually clearer with unpacking: [y for (item, times) in a for y in [item] * times]
tokland
@tokland: +1 that's what I'd have done. But I'd avoid using `times` because it looks too much like a typo of `items`. Use for example `repeat` instead.
Mark Byers
+3  A: 
>>> a = [['a',2], ['b',2], ['c',1]]
>>> [i for i, n in a for k in range(n)]
['a', 'a', 'b', 'b', 'c']
sdcvvc
+1  A: 
import operator
a = [['a',2], ['b',2], ['c',1]]
nums = [[x[0]]*x[1] for x in a]
nums = reduce(operator.add, nums)
Richard Fearn
`reduce(operator.add, ...)` is O(n^2).
KennyTM
+1  A: 

An itertools approach:

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']
tokland
some troubled minds would even devise itertools.chain.from_iterable(itertools.starmap(itertools.repeat, pairs)), but stay away from them ;-)
tokland
A: 
>>> a = [['a',2], ['b',2], ['c',1]]
>>> sum([[item]*count for item,count in a],[])
['a', 'a', 'b', 'b', 'c']
Paul McGuire
+1  A: 

If you prefer extend over list comprehensions:

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