Создание списка одного элемента повторяется N раз в Python

StackOverflow https://stackoverflow.com/questions/3459098

Вопрос

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

Я хочу создать серию списков, все различные длины. Каждый список будет содержать один и тот же элемент 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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top