Повторить первый элемент списка списков по длине

У меня есть список списков Python:

l = [[1, 2, 3], [4], [5, 6], [7, 8, 9, 10]] 

Я хочу, чтобы повторить первый элемент каждого списка в зависимости от длины списка:

 result = [1, 1, 1, 4, 5, 5, 7, 7, 7, 7] 

Я могу добиться этого, используя понимание списка, но мой список очень длинный, поэтому метод медленный:

 result = [[x[0]]*len(x) for x in l] [[1, 1, 1], [4], [5, 5], [7, 7, 7, 7]] 

Хотя это все равно возвращает список списков, а не плоский список. Итак, я пытаюсь выяснить самый быстрый способ создания этого плоского списка на основе критериев, упомянутых выше.

Обновление : мне нужен самый быстрый метод, так как список длинный

Использование itertools.repeat с chain является наиболее эффективным с использованием python 2:

 In [13]: l = [choice(l) for _ in xrange(1000000)] In [14]: timeit list(itertools.chain(*[[i[0]]*len(i) for i in l])) 1 loops, best of 3: 416 ms per loop In [15]: timeit [i[0] for i in l for _ in xrange(len(i))] 1 loops, best of 3: 245 ms per loop In [16]: timeit list(itertools.chain.from_iterable(repeat(i[0],len(i)) for i in l)) 1 loops, best of 3: 223 ms per loop In [17]: timeit [i for x in l for i in [x[0]]*len(x)] 1 loops, best of 3: 332 ms per loop 

Интересно, используя python3 , использование списка вместо выражения генератора выполняется быстрее:

 In [8]: timeit list(chain.from_iterable(repeat(i[0], len(i)) for i in l)) 1 loops, best of 3: 372 ms per loop In [9]: timeit [i[0] for i in l for _ in range(len(i))] 1 loops, best of 3: 433 ms per loop In [10]: timeit list(chain.from_iterable([repeat(i[0],len(i)) for i in l])) 1 loops, best of 3: 296 ms per loop In [11]: timeit list(chain(*[[i[0]]*len(i) for i in l])) 1 loops, best of 3: 460 ms per loop In [12]: timeit [i for x in l for i in [x[0]]*len(x)] 1 loops, best of 3: 348 ms per loop 

Если вам нужен компромисс между временем и пространством, то итерация по объекту цепи получает элемент за раз:

 In [18]: %%timeit for ele in chain.from_iterable([repeat(i[0],len(i)) for i in l]): pass ....: 1 loops, best of 3: 306 ms per lo 

Вы можете использовать itertools.chain, чтобы сгладить ваш результат.

 import itertools l = [[1, 2, 3], [4], [5, 6], [7, 8, 9, 10]] res = list(itertools.chain(*[[i[0]]*len(i) for i in l])) print (res) 

Урожайность:

 [1, 1, 1, 4, 5, 5, 7, 7, 7, 7] 

В соответствии с предложением @PadraicCunningham можно использовать itertools.chain.from_iterable который быстрее сравнения itertools.chain .

 import timeit case1 = lambda: list(itertools.chain(*[[i[0]]*len(i) for i in l])) case2 = lambda: list(itertools.chain.from_iterable([[i[0]]*len(i) for i in l])) print ("time required by Case1 to execute :", timeit.timeit(case1)) print ("time required by Case1 to execute :", timeit.timeit(case2)) 

Показывает отчет о времени для обоих случаев:

 time required by Case1 to execute : 4.83640388816 time required by Case1 to execute : 4.68654976762 
 >>> [i[0] for i in l for _ in range(len(i))] [1, 1, 1, 4, 5, 5, 7, 7, 7, 7] 

Вы могли бы сделать так,

 >>> l = [[1, 2, 3], [4], [5, 6], [7, 8, 9, 10]] >>> [i for x in l for i in [x[0]]*len(x)] [1, 1, 1, 4, 5, 5, 7, 7, 7, 7] 

Остальные ответы очень хорошие. Вот альтернативный ответ 1 с использованием map и reduce

 >>> l = [[1, 2, 3], [4], [5, 6], [7, 8, 9, 10]] >>> reduce(lambda x,y: x+y,map(lambda x:[x[0]]*len(x),l)) [1, 1, 1, 4, 5, 5, 7, 7, 7, 7] 

1 Чтобы вы могли изучать новые модули python.