2010-03-15 5 views
19

Я хочу написать функцию, которая оживляет список [1,5,3,6,...] и дает [1,1,5,5,3,3,6,6,...] любая идея, как это сделать? благодарядублировать каждого члена в списке - python

+2

Звучит домашнее задание. Есть более эффективные способы работы со списком, чем дублирование элементов. –

ответ

12
>>> a = [1, 2, 3] 
>>> b = [] 
>>> for i in a: 
    b.extend([i, i]) 


>>> b 
[1, 1, 2, 2, 3, 3] 

или

>>> [a[i//2] for i in range(len(a)*2)] 
[1, 1, 2, 2, 3, 3] 
+0

Вы должны использовать '//' для деления пола в Python 2. –

+0

@Mike: уверен, что вы правы, за исключением, конечно, в '/' разделе, что возвращается 'int'. – SilentGhost

38
>>> a = range(10) 
>>> [val for val in a for _ in (0, 1)] 
[0, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9] 

нотабене _ традиционно используется в качестве имени переменной-заполнителя, где вы не хотите ничего делать с содержимым переменной. В этом случае он просто используется для генерации двух значений за каждый раз по внешнему циклу.

Чтобы превратить это из списка в генератор, замените квадратные скобки круглыми скобами.

+1

'_', в наши дни используется для i18n/l10n (google). Я все еще стараюсь использовать его * если * Я знаю, что в этом модуле не будет i18n. Else I (будет) использовать '__' (два символа подчеркивания). –

1

Я хотел бы использовать

import itertools 
foo = [1, 5, 3, 6] 
new = itertools.chain.from_iterable([item, item] for item in foo) 

new будет итератор, который лениво перебирает дублированных элементов. Если вам нужен фактический список, вы можете сделать list(new) или использовать одно из других решений.

+1

или короче: 'itertools.chain.from_iterable (itertools.izip (foo, foo))' –

+0

Я считал этот код короче, но мне не показалось яснее. –

6

Если у вас уже есть roundrobin рецепт, описанный в документации itertools -И это очень удобно, то вы можете просто использовать

roundrobin(my_list, my_list) 
+0

+1, это хороший способ добиться этого. –

1

Для целых Guido антипатии функциональных операторов, они могут быть довольно штопала удобно:

>>> from operator import add 
>>> a = range(10) 
>>> b = reduce(add, [(x,x) for x in a]) 
+0

В случае уменьшения, полезно часто означает удивительно медленное. Важно измерить, что делает 'сокращение'. Часто это шокирует, сколько вычислений сокращает силы. –

+0

Я сделал тестовый скрипт с каждым из методов на этой странице с baselist = range (10) и 1,000,000 итераций. Самый медленный результат составил 5.094 секунды, а самый быстрый - 3,622 секунды. Мой пример сокращения составил 3,906 секунды. –

+1

'range (10)' крошечный, поэтому сложность играет небольшую роль. Это решение квадратично; все остальные, которые я вижу здесь, являются линейными. Кроме того, некоторые из них кажутся мне более читабельными. –

8

Я хотел бы использовать zip и itertools.chain.

>>> import itertools 
>>> l = [1,5,3,6,16] 
>>> list(itertools.chain(*zip(l,l))) 
[1, 1, 5, 5, 3, 3, 6, 6, 16, 16] 

Примечание: Я только использовал list потреблять генератор, чтобы сделать его пригодным для печати. Вам, вероятно, не нужен звонок list в вашем коде ...

1

Возможно использование умножения списка. Случай, в котором вам нужен каждый элемент списка, просто использует отсортированный метод.

>>> lst = [1,2,3,4] 
>>> sorted(lst*2) 
[1,1,2,2,3,3,4,4] 
+0

Как насчет того, чтобы сохранить порядок исходного списка? Как насчет того, что элементы в списке неупорядочены? – Moberg