Подтвердить что ты не робот

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

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

Как мне создать списки, не используя понимание списка [e for number in xrange(n)] для каждого списка?

4b9b3361

Ответ 1

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

[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.

Ответ 2

>>> [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]]

Ответ 3

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

Неизменные предметы

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

[e] * 4

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

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

Изменяемые предметы

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

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'])]

Ответ 4

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

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

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

Ответ 5

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

[e for _ in xrange(n)]

Ответ 6

[e] * n

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