Я хочу створити ряд списків, різної довжини. Кожен список буде містити один і той же елемент e
, повторений n
раз (де n
= довжина списку).
Як створити списки, не використовуючи розуміння списку [e for number in xrange(n)]
для кожного списку?
Я хочу створити ряд списків, різної довжини. Кожен список буде містити один і той же елемент e
, повторений n
раз (де n
= довжина списку).
Як створити списки, не використовуючи розуміння списку [e for number in xrange(n)]
для кожного списку?
Відповіді:
Ви також можете написати:
[e] * n
Слід зазначити, що якщо e, наприклад, порожній список, ви отримуєте список з 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
.
[[]] * n
можна отримати несподівані результати. Щоб створити унікальні порожні підсписи , використовуйте для розуміння:[[] for i in range(0,n)]
Створіть список одноразових повторень n разів у Python
Для незмінних елементів, таких як None, bools, ints, floats, strings, кортежі або frozensets, ви можете це зробити так:
[e] * 4
Зауважте, що це найкраще використовувати лише із змінних елементів (рядків, кортежів, фрозенсетів,) у списку, оскільки всі вони вказують на один і той же елемент у тому самому місці пам’яті. Я часто використовую це, коли мені доводиться будувати таблицю зі схемою всіх рядків, так що мені не потрібно давати дуже надмірне відображення на одне.
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'])]
Itertools має функцію саме для цього:
import itertools
it = itertools.repeat(e,n)
Звичайно, itertools
дає вам ітератор замість списку. [e] * n
дає вам список, але, залежно від того, що ви зробите з цими послідовностями, itertools
варіант може бути набагато ефективнішим.
Як зазначали інші, використання оператора * для об'єкта, що змінюється, дублює посилання, тож якщо ви змінюєте один, ви змінюєте їх усі. Якщо ви хочете створити незалежні екземпляри об'єкта, що змінюється, ваш синтаксис xrange - це найбільш піфонічний спосіб зробити це. Якщо вас турбує наявність названої змінної, яка ніколи не використовується, ви можете використовувати анонімну змінну підкреслення.
[e for _ in xrange(n)]
[e] * n
повинні працювати