добавление каждого члена массива снова, сразу после себя

если у меня есть этот массив Python:

mac_tags = [ "global_rtgn", "global_mogn" ]

И я хочу этот массив Python:

mac_tags = [ "global_rtgn", "global_rtgn", "global_mogn","global_mogn" ]

Как я могу создать его программно?


person Terrence Brannon    schedule 06.03.2012    source источник
comment
Зачем вам это нужно? Просто измените все, что использует список, чтобы дублировать записи.   -  person Katriel    schedule 06.03.2012


Ответы (2)


Обратите внимание, что это скорее функциональный способ сделать это и может не быть чистым идиоматическим кодом Python.

data = [[s, s] for s in [ "global_rtgn", "global_mogn" ]]

data = sum (data, [])

print data
person RStrad    schedule 06.03.2012
comment
(a) Это похоже на злоупотребление sum (b) при использовании sum вы теряете возможность использовать zip/izip вместо того, чтобы писать свои собственные. - person Marcin; 06.03.2012
comment
@Marcin: Худшая проблема с этим подходом заключается в том, что это O (n ^ 2). - person Sven Marnach; 06.03.2012
comment
@SvenMarnach: Как так? Наверняка один обход на застежку, плюс один обход на сумму. Или вы имеете в виду, что выделение памяти будет O (n ^ 2)? CPython не может оптимизировать это? - person Marcin; 06.03.2012
comment
@Marcin: оператор + в списках создает новый список. Использование здесь sum() создает новый список на каждой итерации, копируя все, что было накоплено до сих пор. Это можно было бы оптимизировать, но сделать это непросто, а CPython не делает этого. Такое использование sum() считается неправильным, поэтому не будет предпринято никаких усилий для его оптимизации. Использование понимания списка с двумя предложениями for или itertools.chain.from_iterable() считается правильным способом. На самом деле, более вероятно, что будущая версия Python откажется от этого использования sum() (поскольку они уже используются для строк), чем будет оптимизирована. - person Sven Marnach; 06.03.2012
comment
@SvenMarnach: я понимаю семантику + на уровне Python, но до сих пор нет причин, по которым он должен копировать каждый раз, а не оптимизировать конкатенацию. - person Marcin; 06.03.2012
comment
@Marcin: он должен быть скопирован на первом этапе, так как не разрешено изменять объект, переданный в качестве параметра start. И реализация в основном вызывает метод __add__() любых объектов, которые она получает. Оптимизация этого для списков потребует некоторого особого случая в реализации sum(). - person Sven Marnach; 06.03.2012
comment
@SvenMarnach Нет, в sum не требуется никакого специального регистра. Все, что для этого требуется, — это оптимизация __add__, когда левый операнд не имеет ссылок на него вне контекста вызова, и следующее, что с ним произойдет, — это то, что он станет левым операндом другого вызова __add__. В этом случае оптимизирующий компилятор может просто расширить массив, поддерживающий левый операнд, и скопировать содержимое правого операнда в новое пространство. Это не безумно сложная оптимизация. - person Marcin; 06.03.2012
comment
@Marcin: Нет, это было бы не так просто, потому что это изменило бы интерфейс C несовместимым образом. Счетчик ссылок, равный 1, означает, что дальнейших ссылок на Python нет, но вызывающая функция C вполне может содержать внешнюю ссылку — я обсуждал именно это раньше. Это означает, что оптимизация должна быть выполнена в sum(), и для этого потребуются списки особого случая. - person Sven Marnach; 06.03.2012
comment
@SvenMarnach Да, очевидно, я говорю об изменении того, как работает сам интерпретатор Python. Вам нужна конкретная оптимизация в sum только в том случае, если вы предполагаете никаких других изменений в каком-либо коде. - person Marcin; 06.03.2012

person    schedule
comment
Не буду спорить здесь, это просто еще один способ сделать это. - person DzinX; 06.03.2012