Создание списка одного элемента повторяется N раз в Python
-
27-09-2019 - |
Вопрос
Я знаю, что понимание списка сделает это, но мне было интересно, есть ли еще более короче (и больше пиктоник?) Подход.
Я хочу создать серию списков, все различные длины. Каждый список будет содержать один и тот же элемент e, повторяющиеся N раз (где n = длина списка). Как мне создать списки, не делая
[e for number in xrange(n)]
Для каждого списка?
Решение
Вы также можете написать:
[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
Неизменные предметы
Для неизменных предметов, как никто, строки, кортежи или толщины, вы можете сделать это так:
[e] * 4
Обратите внимание, что это лучше всего использовать только с неизменными элементами (строки, кортежами, толщинами,) в списке, потому что все они указывают на тот же элемент в том же месте в памяти. Я часто использую это часто, когда мне нужно создать таблицу с схемой всех строк, так что мне не нужно давать одному одному сопоставлению.
schema = ['string'] * len(columns)
Союзные предметы
Теперь я уже давно использовал Python, и я никогда не видел корпус использования, где я бы сделаю выше сочественным экземпляром. Вместо этого, чтобы получить, скажем, сметный пустой список, набор или Dict, вы должны сделать что-то вроде этого:
list_of_lists = [[] for _ in columns]
Подчеркивание - это просто имя переменных в этом контексте.
Если у вас есть только номер, это было бы:
list_of_lists = [[] for _ in range(4)]
То _
Не совсем особенный, но проверяют стиль среды для кодирования, вероятно, пожаловаться, если вы не собираетесь использовать переменную и использовать любое другое имя.
Предостережения для использования неизменного метода с помощью мусорных элементов:
Остерегайтесь, делая это с помощью смежных объектов, когда вы меняете один из них, все они меняются, потому что они все такой же объект:
foo = [[]] *4
foo[0].append('x')
Foo теперь возвращается:
[['x'], ['x'], ['x'], ['x']]
Но с неизменными объектами вы можете сделать его работать, потому что вы меняете ссылку, а не объект:
>>> l = [0] * 4
>>> l[0] += 1
>>> l
[1, 0, 0, 0]
>>> l = [frozenset()] * 4
>>> l[0] |= set('abc')
>>> l
[frozenset(['a', 'c', 'b']), frozenset([]), frozenset([]), frozenset([])]
Но опять же, подменные объекты не полезны для этого, потому что на месте операции меняют объект, а не ссылку:
l = [set()] * 4
>>> l[0] |= set('abc')
>>> l
[set(['a', 'c', 'b']), set(['a', 'c', 'b']), set(['a', 'c', 'b']), set(['a', 'c', 'b'])]
Itertools имеет функцию только для этого:
import itertools
it = itertools.repeat(e,n)
Конечно itertools
дает вам итератор вместо списка. [e] * n
дает вам список, но, в зависимости от того, что вы будете делать с этими последовательностями, itertools
Вариант может быть гораздо более эффективным.
Поскольку другие указали, используя * оператор * для ссылок на мулюбируемые объекты дубликатов, поэтому, если вы измените один, вы меняете их все. Если вы хотите создать независимые экземпляры смешанного объекта, ваш синтаксис XRANGE - это самый питонический способ сделать это. Если вы беспокоитесь, имея именованную переменную, которая никогда не используется, вы можете использовать анонимную переменную подчеркивание.
[e for _ in xrange(n)]
[e] * n
должно сработать