57

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?

Stas
  • 11,571
  • 9
  • 40
  • 58

6 Answers6

61

Stacked LCs.

[y for x in a for y in [x[0]] * x[1]]
Ignacio Vazquez-Abrams
  • 776,304
  • 153
  • 1,341
  • 1,358
  • 27
    Thanks! It works but I don't even understand how to read this expression. – Stas Oct 10 '10 at 08:58
  • 3
    `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 Oct 10 '10 at 09:00
  • 12
    It is usually clearer with unpacking: [y for (item, times) in a for y in [item] * times] – tokland Oct 10 '10 at 09:05
  • 4
    @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 Oct 10 '10 at 09:09
  • If think this is also called [nested list comprehension](https://www.geeksforgeeks.org/nested-list-comprehensions-in-python/): ```flatten_matrix = [val for sublist in matrix for val in sublist] ``` – Javi Nov 04 '20 at 15:40
14

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
  • 66,169
  • 13
  • 144
  • 170
6
>>> a = [['a',2], ['b',2], ['c',1]]
>>> [i for i, n in a for k in range(n)]
['a', 'a', 'b', 'b', 'c']
sdcvvc
  • 25,343
  • 4
  • 66
  • 102
6

If you prefer extend over list comprehensions:

a = []
for x, y in l:
    a.extend([x]*y)
dheerosaur
  • 14,736
  • 6
  • 30
  • 31
  • 4
    I think he's asking how to do extend from *within* a list comprehension, but I think a simple loop like this is more readable if performance isn't a concern. – shacker Nov 19 '19 at 01:27
2
>>> a = [['a',2], ['b',2], ['c',1]]
>>> sum([[item]*count for item,count in a],[])
['a', 'a', 'b', 'b', 'c']
PaulMcG
  • 62,419
  • 16
  • 94
  • 130
1
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
  • 25,073
  • 7
  • 56
  • 55