2010-10-10 4 views
19

Когда мне нужно добавить несколько одинаковых элементов в списке, я использую list.extend:list.extend и список понимание

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

Результат

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

Но, как сделать подобное со списком понимание?

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

Результат

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

Но мне нужен этот один

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

Любые идеи?

ответ

23

Штабелированные LC.

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

Спасибо! Это работает, но я даже не понимаю, как читать это выражение. – Stas

+0

'for x in a 'извлекает каждый из элементов' a' по одному за раз в 'x'. 'for y in ...' создает новый список из 'x' и извлекает его элементы по одному в' y'. Все это происходит в одно и то же время (более или менее), заставляя все это находиться на одном уровне гнездования. –

+9

Как правило, с распаковкой обычно яснее: [y for (item, times) in a for y in [item] * times] – 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, ...)' is O (n^2). – kennytm

3

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

Если вы предпочитаете проходить по списковых:

a = [] 
for x, y in l: 
    a.extend([x]*y) 
Смежные вопросы