Sequences
Sequences (Послідовності)⚑
Послідовність (Sequence)⚑
Послідовність - ітерабельний об'єкт, який підтримує доступ до елементів за допомогою цілих індексів за допомогою спеціального методу __getitem__()
(або викидає IndexError) і підтримує метод __len__()
, який повертає довжину послідовності.
До основних вбудованих типів послідовностей належать list
, tuple
, str
та bytes
.
Послідовності також можуть відповідно підтримувати методи count()
, index()
, __contains__()
та __reversed__()
та інші.
Які операції підтримують більшість послідовностей⚑
x in s
,x not in s
- чи міститься елемент x у послідовності s (для рядків і послідовностей байтів - чи є x підрядком s)s + t
- конкатенація послідовностейs * n
,n * s
- конкатенація n нерекурсивних копій послідовності ss[i]
- i-й елемент послідовності ss[:]
- створити копію послідовності ss[i:j]
- зріз послідовності s від i до js[i:j:k]
- зріз послідовності s від i до j з кроком klen(s)
- довжина послідовностіmin(s)
- мінімальний елемент послідовностіmax(s)
- максимальний елемент послідовностіs.index(x[, i[, j]])
- індекс першого входження x (опціонально - починаючи з позиції i і до позиції j)s.count(x)
- загальна кількість входжень x у ssum(s)
- сума елементів послідовності
Незмінні послідовності зазвичай реалізують операцію hash(s)
- хеш-значення об'єкта.
Зрізи (slices)⚑
Зрізи (slices) використовуються для доступу до частин послідовностей, таких як списки, кортежі та рядки.
Синтаксис зрізів виглядає так: sequence[start:stop:step]
. - start
: Початковий індекс зрізу (включно). Якщо не вказано, за замовчуванням використовується 0
. - stop
: Кінцевий індекс зрізу (не включається). Якщо не вказано, за замовчуванням до кінця послідовності. - step
: Крок, з яким обираються елементи. Якщо не вказано, за замовчуванням використовується 1
.
Крок також може бути пропущений. Коли ми пишемо [start:stop]
, це повертає всі елементи послідовності від початку (включно) до елементу перед кінцем. Якщо початковий або кінцевий елемент є від'ємним, це означає і-тий елемент з кінця. Крок вказує на приріст або скільки елементів потрібно пропустити. Наприклад, якщо є список [1,2,3,4,5,6,7,8]
, то [1:-2:2]
поверне елементи, починаючи з другого елементу до передостаннього, включно, виводячи кожен другий елемент, тобто [2, 4]
.
Також для роботи зі зрізами є функція slice()
, яка створює об'єкт зрізу, який можна використовувати для витягування підмножини даних зі структури даних.
my_list = [1, 2, 3, 4, 5]
sliced_list = my_list[1:4:2] # [2, 4]
my_slice = slice(1, 4, 2)
type(my_slice) # slice
result = my_list[my_slice] # [2, 4]
reversed_list = my_list[::-1]
print(reversed_list) # Output: [5, 4, 3, 2, 1, 0]
Чи можна змінити окремий символ всередині рядка⚑
Ні, рядки є незмінними. Операції заміни, форматування і конкатенації повертають новий рядок.
Як об'єднати список рядків в один. Як розбити рядок на список рядків⚑
Щоб об'єднати, потрібен метод рядка .join()
. Щоб розбити, метод .split()
.
Як кодувати та декодувати рядки⚑
Кодувати - перетворити Юнікод на байтовий рядок. Викликати метод .encode()
в рядка. Декодувати - відновити рядок з ланцюжка байт. Викликати метод .decode()
на bytes
.
В обох випадках явно передавати кодування, інакше буде використано те, що визначено в системі за замовчуванням. Бути готовим піймати винятки UnicodeEncodeError
, UnicodeDecodeError
.
Константи string
⚑
string.ascii_letters
-'abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ'
string.ascii_uppercase
-'ABCDEFGHIJKLMNOPQRSTUVWXYZ'
string.ascii_lowercase
-'abcdefghijklmnopqrstuvwxyz'
string.digits
-'0123456789'
string.hexdigits
string.octdigits
string.punctuation
string.printable
-string.whitespace
-' \t\n\r\x0b\x0c'
Які є види форматування рядка?⚑
У Python є кілька способів форматування рядків. - оператор %
- format()
- f-strings
- Форматування рядків за допомогою оператора
%
- застарілий спосіб форматування рядків, схожий на використання оператора%
у C (функціяprintf
).
- Форматування рядків за допомогою методу
format()
- більш сучасний спосіб форматування, що використовує методformat()
для підстановки значень у рядки.
- Форматування рядків за допомогою f-рядків (
f-strings
) - синтаксис форматування рядків, представлений у Python 3.6+. Він дозволяє вбудовувати значення змінних безпосередньо у рядок, та працює швидше за аналоги.
Інтернування рядків⚑
Summary
Інтернування рядків – це процес, у якому дві чи більше рядкові змінні, містять однакове значення, посилаються на один і той самий об'єкт у пам'яті.
В Python інтернування рядків відбувається автоматично при створенні рядкових констант у вихідному коді програми. Це означає, що якщо дві або більше строкові константи містять однакове значення, вони будуть посилатися на той самий об'єкт у пам'яті.
Інтернування рядків застосовується для оптимізації використання пам'яті та прискорення виконання програми. Оскільки операція порівняння двох рядків, що посилаються на той самий об'єкт у пам'яті, виконується швидше, ніж порівняння двох рядків, які зберігаються в різних об'єктах у пам'яті.
Python інтернування рядків застосовується для рядкових констант, які складаються з символів ASCII і мають довжину не більше 20 символів. Це пояснюється тим, що довгі рядки можуть займати занадто багато місця в пам'яті, що може призвести до проблем продуктивності.
a = 'hello'
b = 'hello'
print(a is b) # True because both variables refer to the same object in memory
c = 'hello world'
d = 'hello world'
print(c is d) # False because the string "hello world" has space and is not interned
e = '_1234567890123456789'
f = '_1234567890123456789'
print(e is f) # True because the string contains only numbers and the '_' character
В чому різниця між списком і кортежем⚑
Кортеж (tuple), тюпл - це незмінна послідовності. Представлені класом tuple.
Список (list), ліст - це змінна послідовність, яка зазвичай використовується для зберігання однотипних даних (хоча Python не забороняє зберігати в них дані різних типів). Представлені класом list.
На рівні мови вони відрізняються тим, що до кортежу не можна додати або видалити елемент. Внутрішньо list
і tuple
реалізований як масив вказівників на об'єкти в пам'яті.
- Tuple
a = (), a = (25,), a = tuple()
- Оскільки розмір кортежа фіксований, його можна зберігати більш компактно, ніж списки, які потребують додаткового виділення пам'яті для ефективної операції
append()
. - Кортежі зберігаються в одному блоку пам'яті. Кортежі є незмінними, тому не потребують додаткового місця для зберігання нових об'єктів. Це причина, чому створення кортежу є швидшим за створення списку. Це також пояснює невелику різницю в швидкості індексування, яка є швидшою ніж в списках, оскільки в кортежах для індексування слідкує за меншою кількістю вказівників (оскільки структура фіксована).
typedef struct {
PyObject_VAR_HEAD
/* ob_item contains space for 'ob_size' elements.
Items must normally not be NULL, except during construction when
the tuple is not yet visible outside the function that builds it. */
PyObject *ob_item[1];
} PyTupleObject;
- Макрос
PyObject_HEAD
додає лічильник посилань та вказівник на батьківський тип до об'єкта. - Макрос
PyObject_VAR_HEAD
включає в себеPyObject_HEAD
і додає значенняlong ob_ival
, в якому зберігається довжина. -
PyObject *ob_item[1]
- це масив вказівників на об'єкти, які зберігаються в кортежі і є статичним масивом. -
List
a = []
- швидша ініціалізація ніжlist()
- Списки виділяються в двох блоках: фіксованому з усією інформацією об'єкта Python і блоку змінного розміру для даних.
typedef struct {
PyObject_VAR_HEAD
/* Vector of pointers to list elements. list[0] is ob_item[0], etc. */
PyObject **ob_item;
Py_ssize_t allocated;
} PyListObject;
PyObject_VAR_HEAD
- це макрос, який використовується для реалізації базового об'єкта Python. Він містить розмір та посилання на тип об'єкта.PyObject **ob_item
- це масив вказівників на об'єкти, які зберігаються в списку.Py_ssize_t allocated
- це кількість виділеної пам'яті для об'єктів списку. Поле 'allocated' дорівнює розміру буфера, до якого додавання нових елементів відбувається швидко. Якщо кількість елементів 'ob_size' стає рівною 'allocated', то створюється новий масив більшої місткості і копіюються в нього елементи старого масиву. Встановлюється новий 'allocated', який є більшим відносно старого. 'allocated' завжди кратний 4, і модель його зростання наступна: 0, 4, 8, 16, 24, 32, 40, 52, 64, 76 і так далі.
Які операції підтримує list
⚑
list
підтримує наступні операції - s[i] = x
- елемент з індексом i замінюється на x - s[i:j] = t
, s[i:j:k] = t
- елементи з індексами від i до j (з кроком k) замінюються вмістом ітерабельного об'єкта t - del s[i:j]
, del s[i:j:k]
- видалення відповідних елементів з послідовності - s.append(x)
- додавання x в кінець послідовності - s.clear()
- видалення всіх елементів послідовності - s.copy()
- нерекурсивна копія послідовності - s.extend(t)
- додавання всіх елементів ітерабельного об'єкта в кінець послідовності - s.insert(i, x)
- вставка елемента x за індексом i - s.pop()
, s.pop(i)
- повернення значення за індексом i (за замовчуванням - останній елемент) і його видалення з послідовності - s.remove(x)
- видалення першого входження x - s.reverse()
- розвернути послідовність у зворотньому порядку
В чому різниця між масивами (Arrays) та списками (Lists) у Python?⚑
Масиви та списки в Python мають одинаковий спосіб зберігання даних. Проте масиви можуть містити лише елементи одного типу даних, тоді як списки можуть містити елементи будь-якого типу даних.
import array as arr
my_array = arr.array('i', [1, 2, 3, 4])
my_list = [1, 'abc', 1.20]
print(my_array) # array('i', [1, 2, 3, 4])
print(my_list) # [1, 'abc', 1.2]
Як вирівняти вкладений список в Python?⚑
l = [[1, 2, 3], [4, 5], [6], [7, 8, 9]] # => [1, 2, 3, 4, 5, 6, 7, 8, 9]
sum(l, []) # 1
import itertools
data = [[1, 2, 3], [4, 5, 6]]
list(itertools.chain.from_iterable(data)) # 2
Попарно об'єднати два списки⚑
list1 = [1, 2, 3]
list2 = ['a', 'b', 'c']
combined = list(zip(list1, list2))
print(combined) # Output: [(1, 'a'), (2, 'b'), (3, 'c')]
Як зробити список унікальним (без повторюваних елементів)⚑
Варіант з множиною. Не гарантує порядок елементів. Порядок зберігається тільки для невеликих списків.
Варіант з OrderedDict (з версії 3.7 усі словники впорядковані). Гарантує порядок елементів.
>>> from collections import OrderedDict
>>> list(OrderedDict.fromkeys([1, 2, 2, 2, 3, 3, 1]))
[1, 2, 3]
Варіант з циклом. Повільний, але гарантує порядок. Підходить, якщо елементи не можна поміщати всередину множини (наприклад, словники).
Є кортеж з трьох елементів. Призначити змінним a, b, c його значення⚑
Діапазон (range
)⚑
Діапазон (range) - це вбудована функція, що створює об'єкт діапазону, який представляє собою послідовність чисел. range
використовується для ітерації певну кількість разів в циклах for
, та може приймати один, два або три аргументи: початок, кінець і крок. При виклику функції range()
вона повертає об'єкт діапазону, який можна використовувати у циклах або перетворити на список за допомогою list()
.
Синтаксис range
з трьома аргументами виглядає так: range(start, stop, step)
. Де start
- початкове число діапазону (за замовчуванням 0), stop
- кінцеве число діапазону (не включаючи його) та step
- крок (за замовчуванням 1). Наприклад, range(1, 6, 2)
створить об'єкт діапазону, що містить числа 1, 3, та 5.
Важливо зазначити, що об'єкт діапазону не займає велику кількість пам'яті, навіть якщо він представляє арифметичну послідовність чисел. Він є лінивим, що означає, що числа вираховуються в міру потреби.
range
також підтримує доступ по індексу, len()
, але не являється ітератором - він не викидає StopIteration
, та по ньому можна ітеруватись багато разів.
Як порівнюються послідовності⚑
Дві послідовності рівні, якщо вони мають однаковий тип, однакову довжину і відповідні елементи обох послідовностей рівні.
Порівняння виконується елемент за елементом, зіставляючи відповідні елементи двох послідовностей.
Послідовність меншої довжини менша, ніж послідовність більшої довжини. Якщо їх довжини рівні, то результат порівняння дорівнює результату порівняння перших відмінних елементів.
any
та all
⚑
- Функції
any
таall
використовуються для роботи з ітерабельними об'єктами, такими як списки чи кортежі, для перевірки умов. - Функція
any
повертаєTrue
, якщо хоча б один елемент ітерабельного об'єкта задовольняє вказану умову.
Функція all
повертає True
, лише якщо всі елементи ітерабельного об'єкта задовольняють вказану умову.
Що повертає функція enumerate
?⚑
enumerate
повертає ітератор, який містить пари (індекс, елемент) для кожного елемента в об'єкті, який можна ітерувати (список, кортеж, рядок тощо).