article banner

Списки на Python

Це фрагмент книги Python з нуля, яка допоможе вам навчитися програмуванню з нуля. Ви можете знайти його на Allegro, Empik та в інтернет-книгарнях.

Уяви, що Ти пишеш застосунок для створення списків покупок. У Твоєму списку може бути будь-яка кількість продуктів. Отже, якщо Ти хочеш зберігати такий список у змінній, як це зробити? Досі наші змінні містили одиничні значення, а тут нам потрібно зберігати невизначену їх кількість. У Python ми використовуємо для цього список (англ. list), який є певним набором значень. Значення у списку мають порядок і можуть повторюватися. Списки можуть змінюватися, на відміну від кортежів, про які ми поговоримо пізніше.

Списки — це один із найважливіших блоків, які формують програми. Просто поглянь на перший-ліпший інтернет-магазин, і Ти побачиш список товарів, у кожного з яких є свої списки розмірів і варіантів, список продавців, клієнтів, список способів доставки та оплати тощо... Списки є всюди. Тепер поглянь на Facebook. Ти заходиш і бачиш списки публікацій, друзів, відповідей і уподобань. Типова сторінка в інтернеті — це список статей, авторів, коментарів, категорій... Думаю, Ти розумієш. Не дивно, що списки настільки важливі. Отже, дізнаймося, як вони працюють, і як ми можемо їх використовувати.

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

Концептуально список нагадує нескінченно довгу полицю. Предмети на ній можна розміщувати на місцях, пронумерованих, починаючи з 0.

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

У Python ми створюємо списки за допомогою квадратних дужок. Якщо ми залишимо їх порожніми, буде створено порожній список, тобто ми створимо список без жодних елементів.

my_list = []
print(my_list)  # []

 list — це не дуже вдала назва для змінної, оскільки це ім’я класу, який представляє список.

Часто ми хочемо відразу створити список із конкретними значеннями. Тоді ми вставляємо їх у дужки, розділяючи комами.

fruits = ["Яблуко", "Банан", "Слива"]
print(fruits)  # ["Яблуко", "Банан", "Слива"]

Візуалізація списку з трьох предметів: яблуко, банан і слива. Вони займають послідовні позиції від 0 до 2.

У списках, як і у змінних, можна зберігати елементи різних типів.

my_list = [1, "A", True, [], {a: "A"}]
print(my_list)  # [1, "A", True, [], {a: "A"}]

Однак на практиці ми майже завжди використовуємо в одному списку елементи одного типу. Дуже часто список містить об’єкти певного класу, наприклад продукти, користувачів, лікарів або ігри.

Додавання та вилучення елементів

У Python ми можемо змінювати вміст списку, додаючи або видаляючи елементи. Додати елемент у кінець списку можна за допомогою методу append. Як і в нашій метафорі полиці, коли ми ставимо новий предмет, за замовчуванням він займає перше вільне місце за іншими предметами.

fruits = ["Яблуко"]
print(fruits)  # ["Яблуко"]

fruits.append("Банан")
print(fruits)  # ["Яблуко", "Банан"]

fruits.append("Слива")
print(fruits)  # ["Яблуко", "Банан", "Слива"]

Метод append додає елемент на останню позицію списку.

Ми також можемо видаляти елементи. Найпоширеніший спосіб — це метод pop, який забирає останній елемент зі списку. Це дуже схоже на те, як ми знімаємо останню річ із полиці. Коли цей метод викликається, він повертає усунений елемент і в той же час змінює список так, що елемент у ньому зникає.

fruits = ["Яблуко", "Банан", "Слива"]
ret = fruits.pop()
print(ret)  # Слива
print(fruits)  # ["Яблуко", "Банан"]

метод pop вилучає останній елемент зі списку.

Стеж за тим, аби не видаляти елементи з порожнього списку, оскільки це помилка, яка призводить до винятку, який завершить роботу програми.

Вправа: Створення і редагування списків

Заповни пропуски.

values = [True, __, "AAA"]
print(values.pop())  # ____
print(values.pop())  # 42
values.append(88)
print(values)  # _______

pets = ["dog", "cat"]
pets.pop()
pets.append("pig")
print(pets)  # _______
pet = pets.pop()
print(pets)  # _______
print(pet)  # _______

Відповіді в кінці книги.

Звертання до елементів списку

Повертаючись до згаданої метафори полиці, найпростіший спосіб звернутися до її елементів — використати номери під ними. Це так звані індекси елементів. Індекс першого елемента завжди дорівнює нулю 1.

Іноді вживається термін положення елементів, але це поняття недостатньо чітке. Дехто про елемент із індексом 0 каже, що він розташований на першому місці. Щоб уникнути будь-яких розбіжностей серед програмістів у розумінні цього терміна, ми будемо говорити про те, за яким індексом розташований даний елемент.

Щоб отримати елемент із заданим індексом, ми використовуємо квадратні дужки після списку 2. Ця операція не впливає на вміст списку, вона лише дозволяє нам звернутися до одного із елементів.

fruits = ["Яблуко", "Банан", "Слива"]
print(fruits)  # ["Яблуко", "Банан", "Слива"]

print(fruits[1])  # Банан

print(fruits[0])  # Яблуко

print(fruits)  # ["Яблуко", "Банан", "Слива"]

fruit = fruits[2]
print(fruit)  # Слива

Якщо ми хочемо звернутися до першого елемента, ми використовуємо індекс 0. До другого — 1. Але що робити, якщо ми хочемо звернутися до останнього елемента? Якби ми знали розмір списку, ми відняли би від нього 1 і отримали індекс останнього елемента. Однак така операція була би досить складною, тому Python спростив нам завдання. Якщо ми хочемо звернутися до останнього елемента, ми використовуємо значення -1. До передостаннього — -2 і т.д.

fruits = ["Яблуко", "Банан", "Слива"]
print(fruits)  # ["Яблуко", "Банан", "Слива"]

print(fruits[-1])  # Слива

print(fruits[-2])  # Банан

print(fruits)  # ["Яблуко", "Банан", "Слива"]

fruit = fruits[-3]
print(fruit)  # Яблуко

Вправа: Звернення до елементів списку

Що буде виведено в результаті роботи цього коду?

names = ["Ада", "Бартек", "Чарек", "Дарія", "Ева"]

print(names[0])
print(names[3])
print(names[-1])
print(names[-2])
print(names[1])
print(names[-4])

Звернення до елементів за допомогою діапазону

Іншою корисною функцією є можливість звертатися до елементів у певному діапазоні індексів. Ми визначаємо діапазон, вказуючи спочатку індекс, елементи від якого нас цікавлять, двокрапку, а потім індекс, перед яким ми повинні закінчити. Наприклад, якщо нас цікавлять елементи від другого до передостаннього, ми повинні використовувати індекс другого елемента (1) і останнього (тобто -1): 1: -1.

letters = ["A", "B", "C", "D"]

print(letters[1:-1])  # ['B', 'C']
print(letters[0:-2])  # ['A', 'B']
print(letters[0:-1])  # ['A', 'B', 'C']

Щоб вказати діапазон, який не має верхньої межі, ми не вписуємо праворуч від двокрапки нічого. Так само, якщо ми не розмістимо значення ліворуч, це позначатиме діапазон, який починається з першого елемента списку. Отже, двокрапка означає діапазон, який включає всі елементи.

letters = ["A", "B", "C", "D"]

print(letters[2:])  # ['C', 'D']
print(letters[1:])  # ['B', 'C', 'D']
print(letters[:2])  # ['A', 'B']
print(letters[:])  # ['A', 'B', 'C', 'D']

Індекси та діапазони також можна використовувати для усування фрагментів рядків, де індекси відповідають кожній літері. Таким чином "ABC"[1] поверне "B", а "ABCDEF" [1:-1] - "BCDE".

Вправа: Звернення до елементів за допомогою діапазону

Що буде виведено в результаті роботи цього коду?

names = ["Ада", "Бартек", "Чарек", "Дарія", "Ева"]

print(names[0:2])
print(names[2:4])
print(names[:3])
print(names[3:-1])
print(names[1:])
print(names[1:3])
print(names[-3:])
print(names[1:-2])
print(names[:])

Зміна елементів за допомогою діапазону

Використовуючи індекси та діапазони, ми також можемо вказувати значення, які хочемо змінити. Зміна елемента в індексі виглядає так само, як посилання на нього, але нам також потрібно поставити знак рівності (присвоєння) і нове значення.

names = ["Ада", "Бартек", "Чарек"]

names[1] = "Марек"
print(names)  # ['Ада', 'Марек', 'Чарек']

names[-1] = "Ніна"
print(names)  # ['Ада', 'Марек', 'Ніна']

Аналогічно відбувається заміна елементів у діапазоні. Тільки тут праворуч треба розмістити новий список, елементи якого повинні замінити елементи в заданому діапазоні.

names = ["Ада", "Бартек", "Чарек", "Дарія"]

names[1:3] = ["Оля"]
# В діапазоні 1:3 були "Бартек" і "Чарек",
# тепер — "Оля"
print(names)  # ['Ада', 'Оля', 'Дарія']

names[1:2] = ["Пауліна", "Роберт"]
# В діапазоні 1:2 була "Оля"
# тепер — "Пауліна" і "Роберт"
print(names)  # ['Ада', 'Пауліна', 'Роберт', 'Дарія']

names[2:] = []
# Усуваємо елементи, починаючи з другого індексу
print(names)  # ['Ада', 'Пауліна']

names[:1] = []
# Усуваємо перший елемент
print(names)  # ['Пауліна']

names[:] = []
# Так можна очистити весь список
print(names)  # []

Вправа: Зміна елементів списку

Що буде виведено в результаті роботи цього коду?

names = ["Ада", "Бартек", "Чарек"]

names[2] = "Інжир"
print(names)

names[-2] = "Геральт"
print(names)

names = ["Ада", "Бартек", "Чарек"]

names[:1] = []
print(names)

names[2:] = ["Ева", "Галина"]
print(names)

names[1:2] = ["Іза", "Ян"]
print(names)

names[:-1] = ["Кася"]
print(names)

Розмір списку

Нас часто цікавить кількість елементів у списку. Перевірити її можна за допомогою функції len, яка повертає це число.

empty = []
print(len(empty))  # 0

names = ["Яблуко", "Банан"]
print(len(names))  # 2

values = [True, "Слива", None, [], 42]
print(len(values))  # 5
print(len(values[3]))  # 0

Вправа: Розмір і елементи списку

Склади список із літерами від "A" до "F". Який розмір матиме цей список? Який індекс літери Е? Потім створи список із послідовними числами від 5 до 12. Який розмір матиме цей список? Який елемент міститься за індексом 3?

letters = ______________________
print(len(letters))  # ____
print(letters[____])  # E

numbers = ______________________
print(len(numbers))  # ___
print(numbers[3])  # ___

Відповіді в кінці книги.

Перевірка наявності елемента в списку

Дуже часто нам потрібно перевірити, чи містить список конкретний елемент. Наприклад, якщо ми створюємо магазин і маємо список із доступними розмірами футболок, то можемо захотіти перевірити, чи є в наявності вибраний користувачем розмір. Перевіряємо за допомогою слова in між шуканим елементом і списком.

sizes = ["M", "L", "XL", "XXL"]

print("L" in sizes)  # True
print("S" in sizes)  # False
print("XXL" in sizes)  # True

numbers = [3.14, 2.71, 42]

print(1 in numbers)  # False
print(2.71 in numbers)  # True
print(45 in numbers)  # False

Вправа: Перевірка наявності елемента у списку

Що буде виведено в результаті роботи цього коду?

letters = ["A", "C", "E"]

print("A" in letters)
print("B" in letters)
print("C" in letters)

letters[1] = "F"
print("F" in letters)
print("C" in letters)

Додавання та копіювання списків

Так само, як об’єднувати рядки або додавати числа, ми можемо з’єднати два списки. В результаті цієї операції утвориться новий список, який містить ті ж елементи, що й у поєднаних списках.

list1 = [1, True]
list2 = ["A", []]
list3 = list1 + list2
print(list1)  # [1, True]
print(list2)  # ['A', []]
print(list3)  # [1, True, 'A', []]

list1[1] = False
print(list1)  # [1, False]
print(list3)  # [1, True, 'A', []]

Зверни увагу, що зміна list1 не впливає на list3, оскільки list3 є копією об’єднаних списків. Варто на це зважати, адже якщо у нас є дві змінні, які вказують на один список, то зміна списку вплине на елементи, які відображаються для обох змінних. Щоб протидіяти цьому, створюється копія списку (наприклад, за допомогою діапазону, який включає всі елементи).

list1 = ["A", "B"]
list1Ref = list1
list1Copy = list1[:]
list1.append("C")
print(list1)  # ['A', 'B', 'C']
print(list1Ref)  # ['A', 'B', 'C']
print(list1Copy)  # ['A', 'B']

Вправа: Додавання та копіювання списків

Що буде виведено в результаті роботи цього коду?

l1 = ["A", "B"]
l2 = ["D", "E"]
letters = l1 + l2
l1Copy = l1[:]
print(letters)
l1.append("C")
print(l1)
print(letters)
print(l1Copy)

Тапли

Крім списків, у Python є інші способи вираження набору даних. Варто згадати про кортежі (англ. tuple), набори (англ. set) або словники (англ. dictionary). З усіх них ми обговоримо лише кортежі. Два інші способи також цікаві, але менш важливі і не знадобляться нам у наступних частинах.

Термін "tuple" перекладається як "кортеж". Однак цей переклад рідко використовується поза книгами та курсами. У цьому випадку я мав подібну дилему і вирішив використати (можливо, не найточнішу) транскрипцію. Термін "тапл" зрозуміліший, а його використання допомагає простіше перейти на англійську мову, яка є основою в роботі програмістів.

Тапл ("кортеж") — це незмінна сукупність елементів, у якій вони мають свої позиції. Основна відмінність між кортежем і списком полягає у тому, що ви не можете змінювати його елементи. Тому не працюватимуть методи append або pop. Крім того, заборонена заміна за допомогою знаку рівності після елемента або діапазону. Ми створюємо тапл, використовуючи круглі, а не фігурні дужки.

sizes = ("S", "M", "L", "XL")
print(len(sizes))  # 4
print(sizes[0])  # S
print(sizes[1:3])  # ('M', 'L')
print("XXL" in sizes)  # False
print("S" in sizes)  # True

Щоб створити тапл без елементів, достатньо пустих дужок. Ми також можемо використати конструктор tuple без жодних аргументів.

empty = ()
# або
empty = tuple()
print(empty)  # ()

Однак існує проблема зі створенням тапла з одним значенням. Звичайні дужки навколо значення інтерпретуються Python як спосіб визначення порядку операцій. Щоб створити тапл, нам потрібно додати кому після значення.

s = ("XXL")
print(type(s))  # <class 'str'>
new_size = ("XXL",)
print(type(new_size))  # <class 'tuple'>

Сам тапл незмінний, тобто він завжди вказуватиме на ті самі об’єкти, але ми можемо створювати нові кортежі на основі попереднього. У наступному прикладі ми створимо нові кортежі шляхом додавання sizes і new_size, після чого присвоїмо це значення змінній sizes. Отже сам вміст не змінився, але те, на що вказує змінна, змінилося.

sizes = sizes + new_size
print(sizes)  # ('S', 'M', 'L', 'XL', 'XXL')

Вправа: Тапли

Заповніть пропуски.

values = (True, __, "AAA")
print(values[1])  # 42
print(values[2])  # _____
print(values[:1])  # _____

empty = _______
print(len(empty))  # 0
single = _______
print(single)  # ('AAA',)
print(len(single))  # ___

Відповіді в кінці книги.

Завершення

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

1:

Тут є певна відмінність із тим, як елементи нумеруються за межами світу програмування. Наприклад, у готелях зазвичай нумерація починається з кімнати номер 1. Однак не всюди. Я бачу все більше готелів, які позначають номери від 0, як це прийнято в програмуванні. Також у деяких країнах нижній поверх називається нульовим. У програмуванні цей зсув у нумерації зумовлений першими мовами програмування. Тоді це було оптимізацією. Ми не втрачали числа 0, а на основі адреси списку було легше обчислити адресу елемента в пам’яті.

2:

За замовчуванням після змінної, яка вказує на список.