Создать список одного элемента, повторенного n раз в Python

Я знаю, что понимание списка сделает это, но мне было интересно, есть ли еще более короткий (и более Питонический?) подход.

Я хочу создать серию списков, все разной длины. Каждый список будет содержать один и тот же элемент e, повторенный n раз (где n = длина списка). Как создать списки, не делая

[e for number in xrange(n)]

для каждого списка?

6 ответов


вы также можете написать:

[e] * n

вы должны отметить, что если e, например, пустой список, вы получаете список с N ссылками на тот же список, а не N независимых пустых списков.

тестирование производительности

на первый взгляд кажется это повторение-самый быстрый способ создать список из n одинаковых элементов:

>>> timeit.timeit('itertools.repeat(0, 10)', 'import itertools', number = 1000000)
0.37095273281943264
>>> timeit.timeit('[0] * 10', 'import itertools', number = 1000000)
0.5577236771712819

но подождите-это нечестный тест...

>>> itertools.repeat(0, 10)
repeat(0, 10)  # Not a list!!!

функции itertools.repeat на самом деле он не создает список, он просто создает объект, который можно использовать для создания списка, если хотите! Давайте попробуем еще раз, но преобразование в список:

>>> timeit.timeit('list(itertools.repeat(0, 10))', 'import itertools', number = 1000000)
1.7508119747063233

поэтому, если вам нужен список, используйте [e] * n. Если вы хотите лениво генерировать элементы, используйте repeat.


>>> [5] * 4
[5, 5, 5, 5]

будьте осторожны, когда повторяющийся элемент является списком. Список клонироваться не будет: все элементы будут ссылаться на один и тот же список!

>>> x=[5]
>>> y=[x] * 4
>>> y
[[5], [5], [5], [5]]
>>> y[0][0] = 6
>>> y
[[6], [6], [6], [6]]

создать список одного элемента, повторенного n раз в Python

неизменяемые элементы

для неизменяемых элементов, таких как None, strings, tuples или frozensets, вы можете сделать это следующим образом:

[e] * 4

обратите внимание, что это лучше всего использовать только с неизменяемыми элементами (строки, кортежи, frozensets,) в списке, потому что все они указывают на тот же элемент в том же месте в памяти. Я часто использую это, когда мне нужно построить таблицу со схемой всех строки, так что мне не нужно давать отображение один к одному.

schema = ['string'] * len(columns)

изменяемые элементы

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

list_of_lists = [[] for _ in columns]

в этом контексте подчеркивание-это просто выбрасываемое имя переменной.

если у вас есть только номер, что бы быть:

list_of_lists = [[] for _ in range(4)]

на _ на самом деле не особенный, но ваша проверка стиля среды кодирования, вероятно, будет жаловаться, если вы не собираетесь использовать переменную и использовать любое другое имя.


предостережения для использования неизменяемого метода с изменяемыми элементами:

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


Itertools имеет функцию только для этого:

import itertools
it = itertools.repeat(e,n)

конечно itertools дает итератор, а не список. [e] * n дает список, но, в зависимости от того, что вы будете делать с теми последовательностей itertools вариант может быть гораздо более эффективным.


как указывали другие, использование оператора * для изменяемого объекта дублирует ссылки, поэтому, если вы измените один, вы измените их все. Если вы хотите создать независимые экземпляры изменяемого объекта, синтаксис xrange является наиболее подходящие для Python способ сделать это. Если вас беспокоит наличие именованной переменной, которая никогда не используется, Вы можете использовать анонимную переменную подчеркивания.

[e for _ in xrange(n)]

[e] * n

должно работать