Списки Python

Для роботи з наборами даних Python надає такі вбудовані типи як списки, кортежі і словники.

Список list представляє тип даних, який зберігає набір або послідовність елементів. Для створення списку в квадратних дужках ([]) через кому перераховуються всі його елементи. У багатьох мовах програмування є аналогічна структура даних, яка називається масив. Наприклад, визначимо список чисел:

numbers = [1, 2, 3, 4, 5] 

Також для створення списку можна використовувати конструктор list():

numbers1 = []  
numbers2 = list() 

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

Конструктор list для створення списка може приймати інший список:

numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9]  

numbers2 = list(numbers) 

Для звернення до елементів списку треба використовувати індекси, які представляють номер елемента в списку. Індекси починаються з нуля. Тобто другий елемент матиме індекс 1. Для звернення до елементів з кінця можна використовувати негативні індекси, починаючи з -1. Тобто у останнього елемента буде Індекс -1, у передостаннього - -2 і так далі.

numbers = [1, 2, 3, 4, 5]  
print(numbers[0]) # 1  
print(numbers[2]) # 3  
print(numbers[-3]) # 3    

numbers[0] = 125 # змінюємо перший елемент списку  
print(numbers[0]) # 125

Якщо необхідно створити список, в якому повторюється одне і те ж значення кілька разів, то можна використовувати символ зірочки *. Наприклад, визначимо список з шести п'ятірок:

numbers = [5] * 6 # [5, 5, 5, 5, 5, 5]  
print(numbers) 

Крім того, якщо нам необхідний послідовний список чисел, то для його створення зручно використовувати функцію range, яка має три форми:

  • range(end): створюється набір чисел від 0 до числа end
  • range(start, end): створюється набір чисел від числа start до числа end
  • range(start, end, step): створюється набір чисел від числа start до числа end з кроком step
numbers = list(range(10))  
print(numbers) # [0, 1, 2, 3, 4, 5, 6, 7, 8, 9]  
numbers = list(range(2, 10))  
print(numbers) # [2, 3, 4, 5, 6, 7, 8, 9]  
numbers = list(range(10, 2, -2))  
print(numbers) # [10, 8, 6, 4] 

Наприклад, наступні два визначення списку будуть аналогічні, але за рахунок функції range ми скорочуємо обсяг коду:

numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9]  
numbers2 = list(range(1, 10)) 

Список необов'язково повинен містити тільки однотипні об'єкти. Ми можемо помістити в один і той же список рядки, числа, об'єкти інших типів даних:

objects = [1, 2.6, "Hello", True]  

Перебір елементів

Для перебору елементів можна використовувати як цикл for, так і цикл while.

Перебір за допомогою циклу for:

companies = ["Microsoft", "Google", "Oracle", "Apple"]  
for item in companies:  
    print(item)

Тут замість функції range ми відразу можемо підставити наявний список companies.

Перебір за допомогою циклу while:

companies = ["Microsoft", "Google", "Oracle", "Apple"]  
i = 0  
while i < len(companies):  
    print(companies[i])  
    i += 1  

Для перебору за допомогою функції len() отримуємо довжину списку. За допомогою лічильника i виводить по елементу, поки значення лічильника не стане дорівнює довжині списку.

Порівняння списків

Два списки вважаються рівними, якщо вони містять той самий набір елементів:

numbers = [1, 2, 3, 4, 5, 6, 7, 8, 9]  
numbers2 = list(range(1,10))  
if numbers == numbers2:  
    print("numbers equal to numbers2")  
else:  
    print("numbers is not equal to numbers2") 

В даному випадку обидва списки будуть рівні.

Методи і функції по роботі зі списками

Для управління елементами списки мають цілий ряд методів. Деякі з них:

  • append (item): додає елемент item в кінець списку
  • insert(index, item): додає елемент item до списку за індексом index
  • remove(item): видаляє елемент item. Видаляється тільки перше входження елемента. Якщо елемент не знайдено, генерує виняток ValueError
  • clear(): видалення всіх елементів зі списку
  • index(item): повертає індекс елемента item. Якщо елемент не знайдено, генерує виняток ValueError
  • pop([index]): видаляє та повертає елемент за індексом index. Якщо Індекс не переданий, то просто видаляє останній елемент.
  • count (item): повертає кількість входжень елемента item в список
  • sort([key]): сортує елементи. За замовчуванням сортує за зростанням. Але за допомогою параметра key ми можемо передати функцію сортування.
  • reverse (): розставляє всі елементи в списку в зворотному порядку
  • Крім того, Python надає ряд вбудованих функцій для роботи зі списками:
  • len(list): повертає довжину списку
  • sorted (list, [key]): повертає відсортованих список
  • min(list): повертає найменший елемент списку
  • max(list): повертає найбільший елемент списку

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

Для додавання елемента застосовуються методи append() і insert, а для видалення - методи remove(), pop() і clear().

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

users = ["Tom", "Bob"]     

# додаємо в кінець списку  
users.append("Alice") # ["Tom", "Bob", "Alice"]  
# додаємо на другу позицію 
users.insert(1, "Bill") # ["Tom", "Bill", "Bob", "Alice"]  
# отримуємо індекс елемента  
i = users.index("Tom")  
# видаляємо за цим індексом  
removed_item = users.pop(i) # ["Bill", "Bob", "Alice"]     

last_user = users[-1]  
# видаляємо останній елемент  
users.remove(last_user) # ["Bill", "Bob"]     

print(users)     

# видаляємо всі елементи  
users.clear()

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

Якщо певний елемент не знайдений, то методи remove і index генерують виняток. Щоб уникнути подібної ситуації, перед операцією з елементом можна перевіряти його наявність за допомогою ключового слова in:

companies = ["Microsoft", "Google", "Oracle", "Apple"]  
item = "Oracle" # елемент для видалення  
if item in companies:  
    companies.remove(item)     

print(companies)

Вираз item in companies повертає True, якщо елемент item є в списку companies. Тому конструкція if item in companies може виконати наступний блок інструкцій у залежності від наявності елемента в списку.

Підрахунок входжень

Якщо необхідно дізнатися, скільки разів у списку присутній той чи інший елемент, то можна застосувати метод count():

users = ["Tom", "Bob", "Alice", "Tom", "Bill", "Tom"]     

users_count = users.count("Tom")  
print(users_count) # 3 

Сортування

Для сортування за зростанням застосовується метод sort():

users = ["Tom", "Bob", "Alice", "Sam", "Bill"]     

users.sort()  
print(users) # ["Alice", "Bill", "Bob", "Sam", "Tom"]  

Якщо необхідно відсортувати дані в зворотному порядку, то ми можемо після сортування застосувати метод reverse():

users = ["Tom", "Bob", "Alice", "Sam", "Bill"]     

users.sort()  
users.reverse()  
print(users) # ["Tom", "Sam", "Bob", "Bill", "Alice"]

При сортуванні фактично порівнюються два об'єкти, і який з них "менше", ставиться перед тим, який "більше". Поняття "більше" і "менше" досить умовні. І якщо для чисел все просто - числа розташовуються в порядку зростання, то для рядків та інших об'єктів ситуація складніша. Зокрема, рядки оцінюються за першими символами. Якщо перші символи рівні, оцінюються другі символи і так далі. При чому цифровий символ вважається "менше", ніж алфавітний великий символ, а заголовний символ вважається менше, ніж рядковий. Докладніше про порівняння рядків описувалося в статті операції з рядками.

Таким чином, якщо в списку поєднуються рядки з верхнім і нижнім регістром, то ми можемо отримати не зовсім коректні результати, так як для нас рядок "bob" повинна стояти до рядка "Tom". І щоб змінити стандартну поведінку сортування, ми можемо передати в метод sort() в якості параметра функцію:

users = ["Tom", "bob", "alice", "Sam", "Bill"]     

users.sort(key=str.lower)  
print(users) # ["alice", "Bill", "bob", "Sam", "Tom"]  

Крім методу sort ми можемо використовувати вбудовану функцію sorted, яка має дві форми:

  • sorted(list): сортує список list
  • sorted(list, key): сортує список list, застосовуючи до елементів функцію key
users = ["Tom", "bob", "alice", "Sam", "Bill"]     

sorted_users = sorted(users, key=str.lower)  
print(sorted_users) # ["alice", "Bill", "bob", "Sam", "Tom"] 

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

Мінімальне і максимальне значення

Вбудований функції Python min() і max() дозволяють знайти мінімальне і максимальне значення відповідно:

numbers = [9, 21, 12, 1, 3, 15, 18]  
print(min(numbers)) # 1  
print(max(numbers)) # 21 

Копіювання списків

При копіюванні списків слід враховувати, що списки це змінний (mutable) тип, тому якщо обидві змінні будуть вказувати на один і той же список, то зміна однієї змінної, торкнеться і іншої змінної:

users1 = ["Tom", "Bob", "Alice"]  
users2 = users1  
users2.append("Sam")  
# users1 і users2 вказують на один і той же список  
print(users1) # ["Tom", "Bob", "Alice", "Sam"]  
print(users2) # ["Tom", "Bob", "Alice", "Sam"] 

Це так зване "поверхневе копіювання" (shallow copy). І, як правило, така поведінка небажана. І щоб відбувалося копіювання елементів, але при цьому змінні вказували на різні списки, необхідно виконати глибоке копіювання (deep copy). Для цього можна використовувати метод deepcopy(), який визначений у вбудованому модулі copy:

import copy     

users1 = ["Tom", "Bob", "Alice"]  
users2 = copy.deepcopy(users1)  
users2.append("Sam")  
# пееменные users1 і users2 вказують на різні списки  
print(users1) # ["Tom", "Bob", "Alice"]  
print(users2) # ["Tom", "Bob", "Alice", "Sam"]  

Копіювання частини списку

Якщо необхідно скопіювати не весь список, а тільки його якусь певну частину, то ми можемо застосовувати спеціальний синтаксис. який може приймати такі форми:

  • list[:end]: через параметр end передається індекс елемента, до якого потрібно копіювати список
  • list[start:end]: параметр start вказує на індекс елемента, починаючи з якого треба скопіювати елементи
  • list[start:end:step]: параметр step вказує на крок, через який будуть копіюватися елементи зі списку. За замовчуванням цей параметр дорівнює 1.
users = ["Tom", "Bob", "Alice", "Sam", "Tim", "Bill"]     

slice_users1 = users[:3] # з 0 по 3  
print(slice_users1) # ["Tom", "Bob", "Alice"]     

slice_users2 = users[1:3] # з 1 по 3  
print(slice_users2) # ["Bob", "Alice"]     

slice_users3 = users[1:6:2] # з 1 по 6 з кроком 2  
print(slice_users3) # ["Bob", "Sam", "Bill"] 

З'єднання списків

Для об'єднання списків застосовується операція додавання (+):

users1 = ["Tom", "Bob", "Alice"]  
users2 = ["Tom", "Sam", "Tim", "Bill"]  
users3 = users1 + users2  
print(users3) # ["Tom", "Bob", "Alice", "Tom", "Sam", "Tim", "Bill"] 

Списки списків

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

users = [  
    ["Tom", 29],  
    ["Alice", 33], 
    ["Bob", 27]  
]     

print(users[0]) # ["Tom", 29]  
print(users[0][0]) # Tom  
print(users[0][1]) # 29  

Щоб звернутися до елемента вкладеного списку, необхідно використовувати пару індексів: users[0] [1] - звернення до другого елементу першого вкладеного списку.

Додавання, видалення та видалення спільного списку, а також вкладених списків аналогічно тому, як це робиться зі звичайними (одномірними) списками:

users = [  
    ["Tom", 29],  
    ["Alice", 33],  
    ["Bob", 27]  
]  

# створення вкладеного списку  
user = list()  
user.append("Bill")  
user.append(41)  
# додавання вкладеного списку  
users.append(user)     

print(users[-1]) # ["Bill", 41]   

# додавання у вкладений список 
users[-1].append("+79876543210")     

print(users[-1]) # ["Bill", 41, "+79876543210"]     

# видалення останнього елемента з вкладеного списку  
users[-1].pop()  
print(users[-1]) # ["Bill", 41]     

# видалення всього останнього вкладеного списку  
users.pop(-1)     

# зміна першого елемента  
users[0] = ["Sam", 18]  
print(users) # [ ["Sam", 18], ["Alice", 33], ["Bob", 27]]  

Перебір вкладених списків:

users = [  
    ["Tom", 29],  
    ["Alice", 33],
    ["Bob", 27]  
]     

for user in users:
    for item in user:  
        print(item, end=" | ")  

Консольний висновок:

Tom | 29 | Alice | 33 | Bob | 27 |