У Python колекція — це об’єкт, який містить групу елементів і дозволяє працювати з ними як з єдиною цілістю.
Колекції зазвичай підтримують:
- ітерацію (
for елемент in колекція) - перевірку належності (
x in колекція) - визначення довжини (
len(колекція)) - доступ за індексом або ключем (якщо впорядковані або асоціативні)
У Python немає строгого «інтерфейсу колекції», але використовуються неформальні протоколи. Якщо об’єкт реалізує
__iter__,__len__,__contains__, його можна вважати колекцією.
- Що НЕ є колекцією
- Вбудовані колекції
- Розширені колекції зі стандартної бібліотеки
- Інші типи, схожі на колекції
- 1. Списки —
list - 2. Словники —
dict - 3. Кортежі —
tuple - 4. SimpleNamespace
- 5. Множини —
set - 6. Незмінювані множини —
frozenset - 7. namedtuple — іменовані кортежі
- 8. deque — двостороння черга
- 9. Counter — лічильник елементів
- 10. defaultdict — словник зі значеннями за замовчуванням
- 11. dataclass — класи даних
- 12. UserList — користувацькі списки
- 13. UserDict — користувацькі словники
- 📈 Порівняння пам’яті та продуктивності
- 1. Пам’ять:
listvstuplevsarray.array - 2. Швидкість доступу:
listvstuplevsarray.array - 3. Пам’ять:
dictvsSimpleNamespacevsdataclass - 4. Оптимізація пам’яті:
dataclassз__slots__ - 5. Швидкість пошуку:
listvsset - 6. Пам’ять:
setvsfrozenset - 7. Швидкість додавання:
list.appendvsdeque.appendvsdeque.appendleft
- 1. Пам’ять:
- 🧠 Рекомендації щодо продуктивності
- 📊 Порівняння колекцій
- 💡 Коли що використовувати?
Що НЕ є колекцією
Наступні типи не є колекціями, оскільки не містять груп елементів:
int,float,bool— скалярні значенняNone— відсутність значення- функції, модулі, класи — це об’єкти, але не контейнери даних (якщо тільки не містять
__dict__)
Вбудовані колекції
Доступні без імпорту:
| Тип | Опис |
|---|---|
list | Впорядкована, змінювана послідовність. |
tuple | Впорядкована, незмінювана послідовність. |
dict | Впорядковане (від Python 3.7) відображення ключ-значення. |
set | Невпорядкована колекція унікальних елементів. |
frozenset | Незмінювана версія set. |
Розширені колекції зі стандартної бібліотеки
| Тип | Модуль | Призначення |
|---|---|---|
SimpleNamespace | types | Об’єкт з динамічними атрибутами (альтернатива словнику з доступом через .). |
namedtuple | collections | Незмінювана кортеж з іменованими полями. |
deque | collections | Двостороння черга — ефективна для операцій на обох кінцях. |
Counter | collections | Підклас словника для підрахунку хешованих об’єктів. |
defaultdict | collections | Словник зі значеннями за замовчуванням для відсутніх ключів. |
dataclass | dataclasses | Автоматично генерує __init__, __repr__, __eq__ тощо. |
UserList | collections | Базовий клас для користувацьких списків. |
UserDict | collections | Базовий клас для користувацьких словників. |
Інші типи, схожі на колекції
Хоча не завжди називаються «колекціями», ці типи також представляють або зберігають групи даних.
1. str — рядок
Впорядкована, незмінювана послідовність символів.
s = "Python"
print(len(s)) # → 6
print(s[0]) # → P
print('y' in s) # → True
print(list(s)) # → ['P', 'y', 't', 'h', 'o', 'n']
2. bytes, bytearray
bytes— незмінювана послідовність байтів.bytearray— змінювана версія.
b = b"привіт"
print(b[0]) # → 1087 (українська 'п' у UTF-8)
print(len(b)) # → 12 (бо UTF-8 використовує кілька байтів на символ)
ba = bytearray(b"привіт")
ba[0] = 65 # 'A'
print(ba) # → bytearray(b'A\xd1\x80\xd0\xb8\xd0\xb2\xd1\x96\xd1\x82')
3. range
Лінива, впорядкована числова послідовність. Не зберігає елементи в пам’яті.
r = range(3)
print(list(r)) # → [0, 1, 2]
print(1 in r) # → True
print(r[2]) # → 2
4. array.array
Зберігає однорідні числові дані компактно (як у C).
from array import array
arr = array('i', [1, 2, 3]) # 'i' = ціле число зі знаком
print(arr) # → array('i', [1, 2, 3])
5. Генератори та ітератори
Не зберігають дані — генерують їх за запитом. Не підтримують len() чи індексацію.
gen = (x * 2 for x in range(3))
print(list(gen)) # → [0, 2, 4]
# len(gen) → TypeError
6. ChainMap (з collections)
Об’єднує кілька словників у єдиний вигляд — пошук проходить через мапи в порядку.
from collections import ChainMap
d1 = {'a': 1}
d2 = {'b': 2}
cm = ChainMap(d1, d2)
print(cm['a']) # → 1
print(cm['b']) # → 2
7. OrderedDict (з collections)
Словник, який запам’ятовує порядок вставки. Актуальний для Python < 3.7.
from collections import OrderedDict
od = OrderedDict([('a', 1), ('b', 2)])
print(od) # → OrderedDict([('a', 1), ('b', 2)])
8. enum.Enum, enum.Flag
Колекції іменованих констант.
from enum import Enum
class Color(Enum):
RED = 1
GREEN= 2
print(list(Колір)) # → [<Color.RED: 1>, <Color.GREEN: 2>]
9. typing.NamedTuple, typing.TypedDict
Типізовані обгортки навколо namedtuple та dict.
from typing import NamedTuple, TypedDict
class Людина(NamedTuple):
ім'я: str
вік: int
p = Людина("Олена", 25)
class Фільм(TypedDict):
назва: str
рік: int
m: Фільм = {"назва": "Матриця", "рік": 1999}
10. heapq, bisect — інструменти, не колекції
Працюють з колекціями, але не є ними:
heapq— алгоритм черги з пріоритетом через списки.bisect— підтримує порядок у відсортованих списках.
1. Списки — list
Впорядкована, змінювана колекція. Елементи можуть повторюватися, дозволені всі типи.
Використовується, коли потрібна гнучка послідовність: додавання, видалення, зміна елементів.
Створення: []
олег_list = ["Олег", "Київ", 30, "інженер"]
print(f"Створення списку: {олег_list}")
# → Створення списку: ['Олег', 'Київ', 30, 'інженер']
print(f"Елемент за індексом 0: {олег_list[0]}")
# → Елемент за індексом 0: Олег
олег_list[2] = 31
print(f"Після зміни: {олег_list}")
# → Після зміни: ['Олег', 'Київ', 31, 'інженер']
олег_list.append("одружений")
print(f"Після append: {олег_list}")
# → Після append: ['Олег', 'Київ', 31, 'інженер', 'одружений']
олег_list.insert(1, "Україна")
print(f"Після insert: {олег_list}")
# → Після insert: ['Олег', 'Україна', 'Київ', 31, 'інженер', 'одружений']
олег_list.remove("інженер")
print(f"Після remove (значення): {олег_list}")
# → Після remove (значення): ['Олег', 'Україна', 'Київ', 31, 'одружений']
del олег_list[2]
print(f"Після видалення (індекс): {олег_list}")
# → Після видалення (індекс): ['Олег', 'Україна', 31, 'одружений']
олег_list.extend(["хобі", "риболовля"])
print(f"Після extend: {олег_list}")
# → Після extend: ['Олег', 'Україна', 31, 'одружений', 'хобі', 'риболовля']
олег_list.pop()
print(f"Після pop: {олег_list}")
# → Після pop: ['Олег', 'Україна', 31, 'одружений', 'хобі']
2. Словники — dict
Колекція пар ключ → значення. Ключі мають бути хешованими. Від Python 3.7 зберігається порядок вставки.
Корисно для структурованих даних: профілі, конфігурації, JSON.
Створення: {}
олена_dict = {"ім'я": "Олена", "вік": 25, "місто": "Львів", "професія": "художниця"}
print(f"Створення словника: {олена_dict}")
# → Створення словника: {'ім'я': 'Олена', 'вік': 25, 'місто': 'Львів', 'професія': 'художниця'}
print(f"Значення за ключем 'ім'я': {олена_dict['ім'я']}")
# → Значення за ключем 'ім'я': Олена
олена_dict["вік"] = 26
print(f"Після оновлення: {олена_dict}")
# → Після оновлення: {'ім'я': 'Олена', 'вік': 26, 'місто': 'Львів', 'професія': 'художниця'}
олена_dict["хобі"] = "малювання"
print(f"Після додавання пари: {олена_dict}")
# → Після додавання пари: {'ім'я': 'Олена', 'вік': 26, 'місто': 'Львів', 'професія': 'художниця', 'хобі': 'малювання'}
del олена_dict["місто"]
print(f"Після видалення пари: {олена_dict}")
# → Після видалення пари: {'ім'я': 'Олена', 'вік': 26, 'професія': 'художниця', 'хобі': 'малювання'}
хобі = олена_dict.pop("хобі")
print(f"Після pop: {олена_dict}, значення: {хобі}")
# → Після pop: {'ім'я': 'Олена', 'вік': 26, 'професія': 'художниця'}, значення: малювання
print(f"Ключ 'ім'я' існує: {'ім'я' in олена_dict}")
# → Ключ 'ім'я' існує: True
3. Кортежі — tuple
Впорядкована, незмінювана колекція. Підходить для фіксованих даних.
Використовується, коли важлива незмінність: координати, параметри, значення, що повертаються.
Створення: ()
олег_tuple = ("Олег", "Київ", 30, "інженер")
print(f"Створення кортежу: {олег_tuple}")
# → Створення кортежу: ('Олег', 'Київ', 30, 'інженер')
print(f"Елемент за індексом 2: {олег_tuple[2]}")
# → Елемент за індексом 2: 30
# олег_tuple[0] = "Іван" → TypeError
# олег_tuple.append("щось") → AttributeError
- Кортежі використовують менше пам’яті та швидші за списки.
- Ідеально, коли не потрібна змінюваність.
4. SimpleNamespace
Простий клас з types для створення об’єктів з динамічними атрибутами. Доступ через крапку (obj.attr).
Корисний, коли потрібен синтаксис obj.ім'я без визначення класу.
from types import SimpleNamespace
олена_ns = SimpleNamespace(ім'я="Олена", вік=25, місто="Львів")
print(f"Об'єкт: {олена_ns}")
# → Об'єкт: namespace(ім'я='Олена', вік=25, місто='Львів')
print(f"Ім'я: {олена_ns.ім'я}")
# → Ім'я: Олена
олена_ns.вік = 26
print(f"Після зміни: {олена_ns}")
# → Після зміни: namespace(ім'я='Олена', вік=26, місто='Львів')
олена_ns.професія = "художниця"
print(f"З новим атрибутом: {олена_ns}")
# → З новим атрибутом: namespace(ім'я='Олена', вік=26, місто='Львів', професія='художниця')
del олена_ns.місто
print(f"Після видалення: {олена_ns}")
# → Після видалення: namespace(ім'я='Олена', вік=26, професія='художниця')
setattr(олена_ns, "хобі", "малювання")
print(f"Через setattr: {олена_ns}")
# → Через setattr: namespace(ім'я='Олена', вік=26, професія='художниця', хобі='малювання')
delattr(олена_ns, "хобі")
print(f"Через delattr: {олена_ns}")
# → Через delattr: namespace(ім'я='Олена', вік=26, професія='художниця')
- Альтернатива словнику, коли
obj.ім'якраще заobj['ім'я'].
5. Множини — set
Невпорядкована колекція унікальних елементів. Підтримує операції над множинами: об’єднання, перетин, різниця.
Використовується для видалення дублікатів та перевірки належності.
Створення: {} або set()
числа = {1, 2, 3, 3, 2, 1}
print(f"Множина: {числа}")
# → Множина: {1, 2, 3}
числа.add(4)
print(f"Після додавання: {числа}")
# → Після додавання: {1, 2, 3, 4}
числа.remove(2)
print(f"Після видалення: {числа}")
# → Після видалення: {1, 3, 4}
інші = {3, 4, 5}
print(f"Об'єднання: {числа | інші}")
# → Об'єднання: {1, 3, 4, 5}
print(f"Перетин: {числа & інші}")
# → Перетин: {3, 4}
print(f"Різниця: {числа - інші}")
# → Різниця: {1}
6. Незмінювані множини — frozenset
Незмінювана версія set. Може використовуватися як ключ словника або елемент іншої множини.
frozen = frozenset([1, 2, 3, 2])
print(f"frozenset: {frozen}")
# → frozenset: frozenset({1, 2, 3})
інші = frozenset([3, 4])
print(f"Перетин: {frozen & інші}")
# → Перетин: frozenset({3})
print(f"Об'єднання: {frozen | інші}")
# → Об'єднання: frozenset({1, 2, 3, 4})
# frozen.add(5) → AttributeError
7. namedtuple — іменовані кортежі
Незмінювана структура з доступом за іменем поля. Читабельніша за звичайні кортежі.
from collections import namedtuple
Людина = namedtuple("Людина", ["ім'я", "вік", "місто"])
олена = Людина("Олена", 25, "Львів")
print(f"Об'єкт: {олена}")
# → Об'єкт: Людина(ім'я='Олена', вік=25, місто='Львів')
print(f"Ім'я: {олена.ім'я}")
# → Ім'я: Олена
print(f"Вік: {олена[1]}")
# → Вік: 25
# олена.вік = 26 → AttributeError
олена_нова = олена._replace(вік=26)
print(f"Копія зі зміною: {олена_нова}")
# → Копія зі зміною: Людина(ім'я='Олена', вік=26, місто='Львів')
- Ідеально для записів: точки, користувачі, конфігурації — коли важливі незмінність і читабельність.
8. deque — двостороння черга
Оптимізована для швидких операцій на обох кінцях. Ефективніша за list для appendleft, popleft.
from collections import deque
d = deque([1, 2, 3])
print(f"Початковий deque: {d}")
# → Початковий deque: deque([1, 2, 3])
d.appendleft(0)
print(f"Після appendleft: {d}")
# → Після appendleft: deque([0, 1, 2, 3])
d.append(4)
print(f"Після append: {d}")
# → Після append: deque([0, 1, 2, 3, 4])
лівий = d.popleft()
print(f"Після popleft: {лівий}, залишилось: {d}")
# → Після popleft: 0, залишилось: deque([1, 2, 3, 4])
правий = d.pop()
print(f"Після pop: {правий}, залишилось: {d}")
# → Після pop: 4, залишилось: deque([1, 2, 3])
- Використовується в алгоритмах: BFS, кеші LRU, буфери — коли операції на кінцях мають бути швидкими.
9. Counter — лічильник елементів
Рахує частоту елементів у ітерованому об’єкті. Корисний для статистики та аналізу.
from collections import Counter
текст = "абракадабра"
c = Counter(текст)
print(f"Підрахунок літер: {c}")
# → Підрахунок літер: Counter({'а': 5, 'б': 2, 'р': 2, 'к': 1, 'д': 1})
print(f"Частота 'а': {c['а']}")
# → Частота 'а': 5
print(f"Топ 3: {c.most_common(3)}")
# → Топ 3: [('а', 5), ('б', 2), ('р', 2)]
c2 = Counter("буква")
c.update(c2)
print(f"Після update: {c}")
# → Після update: Counter({'а': 6, 'б': 3, 'р': 2, 'к': 2, 'д': 1, 'у': 1, 'в': 1})
- Корисний для аналізу тексту, логів, голосувань — всюди, де потрібно порахувати «що зустрічається найчастіше».
10. defaultdict — словник зі значеннями за замовчуванням
Автоматично створює значення за замовчуванням для відсутніх ключів. Усуває перевірки if key in dict.
from collections import defaultdict
dd_list = defaultdict(list)
dd_list["фрукти"].append("яблуко")
dd_list["фрукти"].append("банан")
print(f"Список: {dict(dd_list)}")
# → Список: {'фрукти': ['яблуко', 'банан']}
dd_int = defaultdict(int)
for char in "абракадабра":
dd_int[char] += 1
print(f"Підрахунки: {dict(dd_int)}")
# → Підрахунки: {'а': 5, 'б': 2, 'р': 2, 'к': 1, 'д': 1}
dd_set = defaultdict(set)
dd_set["міста"].add("Київ")
dd_set["міста"].add("Львів")
print(f"Множина: {dict(dd_set)}")
# → Множина: {'міста': {'Київ', 'Львів'}}
- Усуває повторюваний код на кшталт
if key not in d: d[key] = []. - Робить код чистішим і безпечнішим.
11. dataclass — класи даних
Декоратор, який автоматично генерує __init__, __repr__, __eq__ тощо.
from dataclasses import dataclass
@dataclass
class Людина:
ім'я: str
вік: int
місто: str = "Не вказано"
олена = Людина("Олена", 25)
print(f"Об'єкт: {олена}")
# → Об'єкт: Людина(ім'я='Олена', вік=25, місто='Не вказано')
print(f"Ім'я: {олена.ім'я}")
# → Ім'я: Олена
олена.вік = 26
print(f"Після зміни: {олена}")
# → Після зміни: Людина(ім'я='Олена', вік=26, місто='Не вказано')
боб = Людина("Боб", 30)
print(f"Олена == Боб: {олена == боб}")
# → Олена == Боб: False
@dataclass(frozen=True)
class НезмінюванаЛюдина:
ім'я: str
вік: int
іван = НезмінюванаЛюдина("Іван", 40)
# іван.вік = 41 → FrozenInstanceError
- Замінює ручне написання
__init__,__repr__,__eq__. - Ідеально для DTO, конфігурацій, моделей.
12. UserList — користувацькі списки
Наслідується від collections.UserList. Використовується для створення списків з користувацькою поведінкою.
from collections import UserList
class СписокЗЛогом(UserList):
def append(self, item):
print(f"[LOG] Додавання: {item}")
super().append(item)
def remove(self, item):
print(f"[LOG] Видалення: {item}")
super().remove(item)
log_list = СписокЗЛогом([1, 2, 3])
print(f"Початковий: {log_list}")
# → Початковий: [1, 2, 3]
log_list.append(4)
# → [LOG] Додавання: 4
print(f"Після append: {log_list}")
# → Після append: [1, 2, 3, 4]
log_list.remove(2)
# → [LOG] Видалення: 2
print(f"Після remove: {log_list}")
# → Після remove: [1, 3, 4]
- Корисний для додавання логування, валідації або зміни стандартної поведінки списків.
13. UserDict — користувацькі словники
Наслідується від collections.UserDict. Використовується для створення словників з користувацькою поведінкою.
from collections import UserDict
class СловникМалихЛітер(UserDict):
def __setitem__(self, key, value):
key = key.lower() if isinstance(key, str) else key
super().__setitem__(key, value)
def __getitem__(self, key):
key = key.lower() if isinstance(key, str) else key
return super().__getitem__(key)
ld = СловникМалихЛітер()
ld["Ім'я"] = "Олена"
print(f"Значення для 'Ім'я': {ld['Ім'я']}")
# → Значення для 'Ім'я': Олена
print(f"Значення для 'ім'я': {ld['ім'я']}")
# → Значення для 'ім'я': Олена
print(f"Ключі: {list(ld.keys())}")
# → Ключі: ['ім'я']
- Використовується для нормалізації ключів, валідації, логування, кешування тощо.
📈 Порівняння пам’яті та продуктивності
Вибір колекції впливає на продуктивність та використання пам’яті. Нижче — практичні бенчмарки.
1. Пам’ять: list vs tuple vs array.array
import sys
from array import array
n = 1_000_000
data = list(range(n))
data_t = tuple(range(n))
data_a = array('i', range(n))
print(f"list: {sys.getsizeof(data) / 1024 / 1024:.2f} MB")
# → list: 8.00 MB
print(f"tuple: {sys.getsizeof(data_t) / 1024 / 1024:.2f} MB")
# → tuple: 8.00 MB
print(f"array: {sys.getsizeof(data_a) / 1024 / 1024:.2f} MB")
# → array: 3.81 MB
array.arrayвикористовує ~2x менше пам’яті для чисел.listіtupleвикористовують схожу пам’ять, алеtupleтрохи швидший при ітерації.
2. Швидкість доступу: list vs tuple vs array.array
import time
def time_access(collection, name):
start = time.perf_counter()
total = 0
for i in range(len(collection)):
total += collection[i]
end = time.perf_counter()
print(f"{name}: {end - start:.4f} секунд")
n = 10_000_000
lst = list(range(n))
tpl = tuple(range(n))
arr = array('i', range(n))
time_access(lst, "list") # → list: 1.2000 секунд
time_access(tpl, "tuple") # → tuple: 1.0000 секунд
time_access(arr, "array") # → array: 0.8000 секунд
array.arrayнайшвидший для числових даних.tupleна 10–20% швидший заlist.- Різниця помітна на великих об’ємах.
3. Пам’ять: dict vs SimpleNamespace vs dataclass
d = {"ім'я": "A", "вік": 25, "місто": "X", "хобі": "Y", "робота": "Z"}
ns = SimpleNamespace(ім'я="A", вік=25, місто="X", хобі="Y", робота="Z")
dc = ЛюдинаDC("A", 25, "X", "Y", "Z")
print(f"dict: {sys.getsizeof(d)} байт") # → 232
print(f"SimpleNamespace: {sys.getsizeof(ns)} байт") # → 64
print(f"dataclass: {sys.getsizeof(dc)} байт") # → 64
print(f"ns.__dict__: {sys.getsizeof(ns.__dict__)} байт") # → 232
SimpleNamespaceіdataclassвикористовують стільки ж пам’яті, скількиdict, через__dict__.- Використовуйте
__slots__для економії пам’яті.
4. Оптимізація пам’яті: dataclass з __slots__
@dataclass
class ЛюдинаСлоти:
__slots__ = ("ім'я", "вік", "місто", "хобі", "робота")
ім'я: str
вік: int
місто: str
хобі: str
робота: str
dc_slots = ЛюдинаСлоти("A", 25, "X", "Y", "Z")
print(f"dataclass + slots: {sys.getsizeof(dc_slots)} байт")
# → 80 байт
# dc_slots.нове = "значення" → AttributeError
__slots__економить пам’ять і прискорює доступ до атрибутів.- Недолік: не можна додавати атрибути динамічно.
5. Швидкість пошуку: list vs set
n = 1_000_000
lst = list(range(n))
st = set(range(n))
def time_in(collection, target, name):
start = time.perf_counter()
for _ in range(1000):
_ = target in collection
end = time.perf_counter()
print(f"{name} (пошук {target}): {end - start:.4f} секунд")
time_in(lst, 999_999, "list") # → 10.0000 секунд
time_in(st, 999_999, "set") # → 0.0005 секунд
setу тисячі разів швидший заlistдля перевірки належності.- Завжди використовуйте
setдля частого перевіркиx in collection.
6. Пам’ять: set vs frozenset
s = set(range(1000))
fs = frozenset(range(1000))
print(f"set: {sys.getsizeof(s)} байт") # → 32792
print(f"frozenset: {sys.getsizeof(fs)} байт") # → 32792
frozensetіsetвикористовують однакову пам’ять.- Різниця лише в змінюваності.
7. Швидкість додавання: list.append vs deque.append vs deque.appendleft
from collections import deque
import time
def time_append(collection, n, method='append'):
start = time.perf_counter()
for i in range(n):
if method == 'appendleft' and hasattr(collection, 'appendleft'):
collection.appendleft(i)
else:
collection.append(i)
end = time.perf_counter()
return end - start
n = 100_000
lst = []
dq = deque()
time_list_append = time_append(lst, n) # → 0.0100 секунд
time_deque_append = time_append(dq, n) # → 0.0100 секунд
time_deque_appendleft = time_append(deque(), n, 'appendleft') # → 0.0100 секунд
# list.insert(0):
lst = []
start = time.perf_counter()
for i in range(n):
lst.insert(0, i)
end = time.perf_counter()
print(f"list.insert(0): {end - start:.4f} секунд") # → 5.0000 секунд
deque.appendleftпрацює за O(1), на відміну відlist.insert(0), який O(n).- Використовуйте
dequeдля частих операцій на обох кінцях.
🧠 Рекомендації щодо продуктивності
| Ситуація | Використовуйте | Причина |
|---|---|---|
| Зберігання чисел, пам’ять критична | array.array | У 2 рази менше пам’яті, швидший доступ |
| Незмінювані дані | tuple | Швидший за list, безпечніший |
Часті перевірки x in collection | set / frozenset | O(1) проти O(n) для list |
| Операції на обох кінцях | deque | appendleft/popleft за O(1) |
| Структуровані дані, пам’ять критична | dataclass + __slots__ | Без __dict__, менше пам’яті |
| Підрахунок частот | Counter | Оптимізовано для цього завдання |
| Користувацька поведінка | UserList / UserDict | Безпечне розширення вбудованих колекцій |
📊 Порівняння колекцій
| Тип | Впорядкований | Змінюваний | Унікальні елементи | Доступ за індексом | Дублікати |
|---|---|---|---|---|---|
list | ✅ Так | ✅ Так | ❌ Ні | ✅ Так | ✅ Так |
tuple | ✅ Так | ❌ Ні | ❌ Ні | ✅ Так | ✅ Так |
dict | ✅ Так* | ✅ Так | Лише ключі | ❌ Ні | Значення: ✅ |
set | ❌ Ні | ✅ Так | ✅ Так | ❌ Ні | ❌ Ні |
frozenset | ❌ Ні | ❌ Ні | ✅ Так | ❌ Ні | ❌ Ні |
SimpleNamespace | ✅ Так (атрибути) | ✅ Так | ❌ Ні (атрибути можуть повторюватися семантично) | ❌ Ні | ✅ Так |
namedtuple | ✅ Так | ❌ Ні | ❌ Ні | ✅ Так | ✅ Так |
deque | ✅ Так | ✅ Так | ❌ Ні | ✅ Так | ✅ Так |
Counter | ❌ Ні | ✅ Так | ❌ Ні | ❌ Ні (але має ключі) | ✅ Так |
defaultdict | ✅ Так* | ✅ Так | Лише ключі | ❌ Ні | Значення: ✅ |
dataclass | ✅ Так (поля) | ✅ Так (якщо не frozen) | ❌ Ні | ❌ Ні | ✅ Так |
UserList | ✅ Так | ✅ Так | ❌ Ні | ✅ Так | ✅ Так |
UserDict | ✅ Так* | ✅ Так | Лише ключі | ❌ Ні | Значення: ✅ |
str | ✅ Так | ❌ Ні | ❌ Ні | ✅ Так | ✅ Так |
bytes | ✅ Так | ❌ Ні | ❌ Ні | ✅ Так | ✅ Так |
bytearray | ✅ Так | ✅ Так | ❌ Ні | ✅ Так | ✅ Так |
range | ✅ Так | ❌ Ні | ❌ Ні | ✅ Так | ❌ Ні |
array.array | ✅ Так | ✅ Так | ❌ Ні | ✅ Так | ✅ Так |
ChainMap | ✅ Так* | ✅ Так | Лише ключі | ❌ Ні | Значення: ✅ |
Enum | ✅ Так | ❌ Ні | ✅ Так (елементи) | ❌ Ні | ❌ Ні |
- — від Python 3.7,
dict,defaultdict,UserDict,ChainMapзберігають порядок вставки.
💡 Коли що використовувати?
| Завдання | Колекція |
|---|---|
| Змінювана послідовність | list / deque / UserList / bytearray |
| Незмінювані дані | tuple / namedtuple / frozenset / str / bytes |
| Швидкий пошук, видалення дублікатів | set / frozenset |
| Структуровані дані | dict / dataclass / SimpleNamespace / UserDict / TypedDict |
| Використання як ключ словника | frozenset |
Тимчасові об’єкти з доступом через . | SimpleNamespace / dataclass |
| Підрахунок частот | Counter |
| Значення за замовчуванням для ключів | defaultdict |
| Ефективні операції на кінцях | deque |
| Користувацька поведінка списку | UserList |
| Користувацька поведінка словника | UserDict |
| Бінарні дані | bytes / bytearray / array.array |
| Конфігурації з ієрархією | ChainMap |
| Іменовані константи | Enum |
| Ліниві послідовності | range / генератори |