2.7. Списки

Список — це змінювана, впорядкована послідовність значень. На відміну від рядків і байтів, списки можуть містити значення будь-яких типів, і ви можете змінювати, додавати або видаляти елементи на місці.

2.7.1. Створення списків

Квадратні дужки створюють літерал списку:

empty   = []
nums    = [1, 2, 3]
mixed   = [1, "two", 3.0, True, None]    # any types
nested  = [[1, 2], [3, 4], [5, 6]]       # lists of lists

Конструктор list будує список з будь-якого ітерованого об’єкта:

>>> list("abc")
['a', 'b', 'c']
>>> list(range(5))
[0, 1, 2, 3, 4]

2.7.2. Довжина, індексування та зрізи

len() повертає кількість елементів. Індексування та зрізи працюють так само, як і з рядками — позиції починаються з 0, від’ємні індекси відраховуються з кінця, а зріз поза допустимим діапазоном мовчки обрізається, не викидаючи виключення:

>>> nums = [10, 20, 30, 40, 50]
>>> len(nums)
5
>>> nums[0]
10
>>> nums[-1]
50
>>> nums[1:4]
[20, 30, 40]
A list of six cells, with positive indices 0..5 above and negative indices -6..-1 below each cell.

Позитивні індекси відраховуються з початку; від’ємні індекси — з кінця.

Синтаксис зрізу є скороченням для об’єкта slice, який Python будує за лаштунками. nums[1:4] — це те саме, що nums[slice(1, 4)]. Явно конструювати зріз доводиться рідко, але slice() інколи корисний для збереження зрізу як значення для повторного використання:

head = slice(0, 3)
print(nums[head])             # [10, 20, 30]
print(letters[head])          # first three letters, same slice

2.7.3. Зміна списку

Списки підтримують присвоєння за індексом та зрізом на місці:

>>> nums = [10, 20, 30]
>>> nums[0] = 99
>>> nums
[99, 20, 30]
>>> nums[1:3] = [200, 300, 400]    # slice can change the length
>>> nums
[99, 200, 300, 400]

Найпоширеніші методи списку:

  • list.append() — додає один елемент у кінець.

  • list.extend() — додає кожен елемент з ітерованого об’єкта.

  • list.insert() — вставляє на задану позицію.

  • list.remove() — видаляє перше входження значення.

  • list.pop() — видаляє та повертає елемент (останній за замовчуванням).

  • list.clear() — видаляє всі елементи.

  • list.sort() — сортує на місці. Передайте reverse=True для сортування у зворотному порядку.

  • list.reverse() — обертає порядок на місці.

>>> nums = []
>>> nums.append(1)
>>> nums.extend([2, 3])
>>> nums.insert(0, 99)
>>> nums
[99, 1, 2, 3]
>>> nums.pop()
3
>>> nums.sort()
>>> nums
[1, 2, 99]

Ці методи змінюють список на місці та повертають None. Запис

nums = nums.sort()    # nums is now None -- common bug

майже ніколи не є тим, що вам потрібно; оригінальний nums було відсортовано, але потім присвоєння перезаписує ім’я поверненим значенням. Або викликайте nums.sort() на окремому рядку, або використовуйте вбудований sorted(), щоб отримати новий відсортований список без зміни оригіналу.

2.7.4. Оператори

  • + об’єднує два списки в новий список.

  • * повторює список.

  • in перевіряє наявність елемента.

>>> [1, 2] + [3, 4]
[1, 2, 3, 4]
>>> [0] * 5
[0, 0, 0, 0, 0]
>>> 3 in [1, 2, 3]
True

2.7.5. Ітерація по списку

Цикл for обходить елементи по порядку:

for n in [10, 20, 30]:
    print(n)

2.7.6. Псевдоніми та змінюваність

Список — це єдине значення в пам’яті; кілька імен можуть вказувати на той самий список. Зміна через одне ім’я видима через будь-яке інше ім’я, що вказує на той самий список.

Two variables a and b both pointing at the same list object; appending to a is visible through b.

a і b обидві вказують на той самий список. Зміна через будь-яке ім’я впливає на те, що бачить кожне інше ім’я.

>>> a = [1, 2, 3]
>>> b = a
>>> a.append(4)
>>> b
[1, 2, 3, 4]                # same object, change is visible

Щоб зробити незалежну копію, зробіть зріз усього списку або викличте конструктор list:

>>> c = a[:]                # or list(a)
>>> a.append(5)
>>> c
[1, 2, 3, 4]                # c is unaffected

Це копіює лише верхній рівень списку; вкладені списки все ще спільно використовуються оригіналом і копією.