Создать список одного элемента, повторяющегося 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)]
The
_
на самом деле не является особенным, но ваша проверка стиля среды кодирования, вероятно, будет жаловаться, если вы не собираетесь использовать переменную и использовать любое другое имя.
предостережения для использования неизменяемого метода с изменяемыми элементами:
остерегайтесь делать это с изменяемыми объектами, когда вы меняете один из них, они все меняются, потому что они все то же самое
Itertools имеет функцию только для этого:
import itertools it = itertools.repeat(e,n)
конечно
itertools
дает итератор, а не список.[e] * n
дает список, но, в зависимости от того, что вы будете делать с теми последовательностейitertools
вариант может быть гораздо более эффективным.
как указывали другие, использование оператора * для изменяемого объекта дублирует ссылки, поэтому, если вы измените один, вы измените их все. Если вы хотите создать независимые экземпляры изменяемого объекта, ваш синтаксис xrange-это самый Питонический способ сделать это. Если вас беспокоит наличие именованной переменной, которая никогда не используется, Вы можете использовать анонимную переменную подчеркивания.
[e for _ in xrange(n)]