====== Перечислимые типы (iterable) ====== ===== Базовые перечислимые типы ===== ^ Тип ^ Название ^ Объявление ^ Порядок ^ | ''list'' | Список | [1, 2, 1], ["a", "b", "a"], [] | Да | | ''tuple'' | Кортеж | (1, 2, 1), ("a", "b", "a"), ("a",) | Да | | ''set'' | Набор | {1, 3, 2}, {"a","c","b"}, set() | Нет | | ''dict'' | Словарь | {"a":1, "c":2, "b":1}, {} | Нет | Перечислимые типы являются изменяемыми (mutable). При присвоении переменные этих типов не копируются. Типы ''tuple'', ''str'' и ''bytes'' имеют промежуточный статус. Они является неизменяемыми, но переменные этих типов можно перечислять.
===== Особенности перечислимых типов ===== * Элементы перечислимых типов могут быть произвольного, в том числе перечислимого типа: data = [5,7,9,12,"test",True,["ab","cd","ef"]] * Списки и кортежи сохраняют порядок, а наборы и словари - нет: data_list = [5,4,3,6,2,1] data_set = {5,4,3,6,2,1} print(data_list) # [5, 4, 3, 6, 2, 1] print(data_set) # {1, 2, 3, 4, 5, 6} * Переменные перечислимых типов (как и все составных) при присвоении не копируются: data = [5,7,9,12] double_data = data double_data[1] = 42 print(data) # [5, 42, 9, 12] * Переменные перечислимых типов можно перечислять.
===== Итерационный цикл for ===== Цикл ''for'' используется для перебора элементов в переменных перечислимых типов. Синтаксис: for <новая переменная> in <переменная перечислимого типа> : ␣␣␣␣<оператор> ␣␣␣␣<оператор> Примеры: data = ['a', 'b', 'c', 'd'] for x in data: print(x)
===== Список: list ===== * Используется в качестве замены массивам и векторам * Может иметь произвольную длину * Его можно удлинять и укорачивать ==== Индексирование списков ==== Индексирование в Python выполняется с 0. data = ['a', 'b', 'c', 'd'] data[0] # 'a' data[3] # 'd' data[4] # Ошибка: выход за пределы списка # Отрицательные индексы нумеруют список с конца и с -1 data[-1] # 'd' data[-4] # 'a' # Длина x = len(data) # x == 4 # Поиск по значению x = data.index('c') # x == 2
==== Срезы списков ==== Срезы (slices) — это способ получать из списка его часть не прибегая к циклам. Синтаксис: ''<индекс первого элемента>:<индекс последнего элемента +1>'' ''<индекс первого элемента>:<индекс последнего элемента +1>:<шаг>'' data = ['a', 'b', 'c', 'd'] data[1:3] # ['b', 'c'] data[2:] # ['c', 'd'] data[:] # ['a', 'b', 'c', 'd'] data[-2:] # ['c', 'd'] data[1:4:2] # ['b', 'd']
Срезы создают копию списка. data = ['a', 'b', 'c', 'd'] # нет копирования temp и data это один список с двумя именами temp = data temp[0] = 'z' # data[0] == 'z' # есть копирование temp и data это разные списки temp = data[:] temp[0] = 'z' # data[0] == 'a'
==== Модификация списков ==== Изменения в самом списке: data = ['a', 'b', 'c', 'd'] data[1] = 42 # data == ['a', 42, 'c', 'd'] del data[1] # data == ['a', 'c', 'd'] data.insert(0,42) # data == [42, 'a', 'c', 'd'] data.append(42) # data == [42, 'a', 'c', 'd', 42] data = data + [1,2,3] # data == [42, 'a', 'c', 'd', 42, 1, 2, 3] v = data.pop() # v == 3, data == [42, 'a', 'c', 'd', 42, 1, 2] v = data.pop(0) # v == 42, data == ['a', 'c', 'd', 42, 1, 2]
==== Обход списков ==== data = ['a', 'b', 'c', 'd'] for v in data: print(v) # a b c d for i,v in enumerate(data): print(i,v) # 0 a 1 b 2 c 3 d Если элемент списка неизменяемого типа, то при присвоение переменной созданной в цикле ''for'' (в примере, ''v'') нового значение не меняет содержание массива. i = 0 while i < len(data): data[i] = 42 i += 1 for i in range(0,len(data)): data[i] = 42 Явное изменение списка.
===== Кортеж: tuple ===== Кортеж это неизменяемый список. tple = (1, 2, 3) tple[0] # 1 tple[0] = 0 # Ошибка tple.append(0) # Ошибка
===== Набор: set ===== Набор не сохраняет порядок. Все элементы набора различны. vset = {4, 3, 2, 3, 1} print(vset) # {1, 2, 3, 4} vset[0] # Ошибка vset.add(0) # {0, 1, 2, 3, 4} vset.add(4) # {0, 1, 2, 3, 4} vset.remove(4) # {0, 1, 2, 3} Типичное применение — удаление дубликатов из списка: data = [1, 1, 2, 2, 2] data = list(set(data)) # [1, 2]
===== Словарь: dict ===== * Набор пар ключ-значение. Ключи всегда различны. * Значения могут быть любого типа, ключи — с некоторыми ограничениями. data = {"a":1, "b":2, "c":3} data["b"] # 2
==== Модификация словарей ==== data = {"a":1, "b":2, "c":3} data["b"] = 3 # data == {"a":1, "b":3, "c":3} del data["b"] # data == {"a":1, "c":3} data["f"] = 99 # data == {'a': 1, 'f': 99, 'c': 3} x = len(data) # x == 3 data.update({"a":99, "q":64}) # data == {'a': 99, 'f': 99, 'q': 64, 'c': 3}
==== Обход словарей ==== data = {"a":1, "b":2, "c":3} for k in data: print(k) # a c b print(data[k]) # 1 3 2 for k in sorted(data.keys()): print(k,data[k]) # a 1 b 2 c 3
===== Копирование переменных составных типов ===== При присвоении переменные составных типов (и в частности перечислимых) не копируются: data = {"a":1, "b":2, "c":3} new_data = data new_data["a"] = 42 print(data["a"]) # 42 !!!
===== Копирование переменных составных типов ===== Для их копирования используются срезы и методы ''copy'' и ''deepcopy'' из модуля ''copy'': import copy data = {"a":1, "b":2, "c":3} new_data = copy.copy(data) # Поверхностная копия new_data["a"] = 42 print(data["a"]) # 1 data = {"a":1, "b":[2,3,4], "c":3} new_data = copy.deepcopy(data) # Полная копия new_data["b"][0] = 42 print(data["b"]) # [2,3,4]
===== Сортировка списков ===== adata = [5,4,2,1,4] # Сортировка с копированием bdata = sorted(adata) # bdata == [1, 2, 4, 4, 5] # Сортировка на месте (in-place) adata.sort() # adata == [1, 2, 4, 4, 5] # Обратная сортировка bdata = sorted(adata, reverse=True) #[5, 4, 4, 2, 1] adata.sort(reverse=True) #[5, 4, 4, 2, 1]
===== Приведение перечислимых типов ===== ^ ^ Исходный тип ''data'' ^^^^ ^ Целевой тип ^ ''list'' ^ ''tuple'' ^ ''set'' ^ ''dict'' ^ ^ ''list'' | | ''list(data)'' | ''list(data)'' | ''list(data.keys()), list(data.values())'' | ^ ''tuple'' | ''tuple(data)'' | | ''tuple(data)'' | ''tuple(data.keys()), tuple(data.values())'' | ^ ''set'' | ''set(data)'' | ''set(data)'' | | ''set(data.keys()), set(data.values())'' | ^ ''dict'' | ''dict(zip(keys,data))'' | ''dict(zip(keys,data))'' | ''dict(zip(keys,data))'' | |