ВУЗ: Не указан
Категория: Не указан
Дисциплина: Не указана
Добавлен: 05.12.2023
Просмотров: 847
Скачиваний: 3
ВНИМАНИЕ! Если данный файл нарушает Ваши авторские права, то обязательно сообщите нам.
СОДЕРЖАНИЕ
Глава 8. Списки, кортежи, множества и диапазоны
169 if i > 10: break print(i, end=" ")
0 1 2 3 4 5 6 7 8 9 10
>>> list(zip(itertools.count(), "абвгд"))
[(0, 'а'), (1, 'б'), (2, 'в'), (3, 'г'), (4, 'д')]
>>> list(zip(itertools.count(start=2, step=2), "абвгд"))
[(2, 'а'), (4, 'б'), (6, 'в'), (8, 'г'), (10, 'д')]
cycle(<Последовательность>)
— на каждой итерации возвращает очередной элемент последовательности. Когда будет достигнут конец последовательности, перебор начнет- ся сначала, и так до бесконечности:
>>> n = 1
>>> for i in itertools.cycle("абв"): if n > 10: break print(i, end=" ") n += 1 а б в а б в а б в а
>>> list(zip(itertools.cycle([0, 1]), "абвгд"))
[(0, 'а'), (1, 'б'), (0, 'в'), (1, 'г'), (0, 'д')]
repeat(<Объект>[, <Количество повторов>])
— возвращает объект указанное количест- во раз. Если количество повторов не указано, объект возвращается бесконечно:
>>> list(itertools.repeat(1, 10))
[1, 1, 1, 1, 1, 1, 1, 1, 1, 1]
>>> list(zip(itertools.repeat(5), "абвгд"))
[(5, 'а'), (5, 'б'), (5, 'в'), (5, 'г'), (5, 'д')]
8.17.2. Генерирование комбинаций значений
Получить различные комбинации значений позволяют следующие функции:
combinations()
— на каждой итерации возвращает кортеж, содержащий комбинацию из указанного количества элементов. При этом элементы в кортеже гарантированно будут разными. Формат функции: combinations(<Последовательность>, <Количество элементов>)
Примеры:
>>> import itertools
>>> list(itertools.combinations('абвг', 2))
[('а', 'б'), ('а', 'в'), ('а', 'г'), ('б', 'в'), ('б', 'г'),
('в', 'г')]
>>> ["".join(i) for i in itertools.combinations('абвг', 2)]
['аб', 'ав', 'аг', 'бв', 'бг', 'вг']
>>> list(itertools.combinations('вгаб', 2))
[('в', 'г'), ('в', 'а'), ('в', 'б'), ('г', 'а'), ('г', 'б'),
('а', 'б')]
>>> list(itertools.combinations('абвг', 3))
[('а', 'б', 'в'), ('а', 'б', 'г'), ('а', 'в', 'г'),
('б', 'в', 'г')]
170
Часть I. Основы языка Python
combinations_with_replacement()
— на каждой итерации возвращает кортеж, содержа- щий комбинацию из указанного количества элементов. При этом кортеж может содер- жать одинаковые элементы. Формат функции: combinations_with_replacement(<Последовательность>,
<Количество элементов>)
Примеры:
>>> list(itertools.combinations_with_replacement('абвг', 2))
[('а', 'а'), ('а', 'б'), ('а', 'в'), ('а', 'г'), ('б', 'б'),
('б', 'в'), ('б', 'г'), ('в', 'в'), ('в', 'г'), ('г', 'г')]
>>> list(itertools.combinations_with_replacement('вгаб', 2))
[('в', 'в'), ('в', 'г'), ('в', 'а'), ('в', 'б'), ('г', 'г'),
('г', 'а'), ('г', 'б'), ('а', 'а'), ('а', 'б'), ('б', 'б')]
permutations()
— на каждой итерации возвращает кортеж, содержащий комбинацию из указанного количества элементов. Если количество элементов не указано, то использу- ется длина последовательности. Формат функции: permutations(<Последовательность>[, <Количество элементов>])
Примеры:
>>> list(itertools.permutations('абвг', 2))
[('а', 'б'), ('а', 'в'), ('а', 'г'), ('б', 'а'), ('б', 'в'),
('б', 'г'), ('в', 'а'), ('в', 'б'), ('в', 'г'), ('г', 'а'),
('г', 'б'), ('г', 'в')]
>>> ["".join(i) for i in itertools.permutations('абвг')]
['абвг', 'абгв', 'авбг', 'авгб', 'агбв', 'агвб', 'бавг',
'багв', 'бваг', 'бвга', 'бгав', 'бгва', 'вабг', 'вагб',
'вбаг', 'вбга', 'вгаб', 'вгба', 'габв', 'гавб', 'гбав',
'гбва', 'гваб', 'гвба']
product()
— на каждой итерации возвращает кортеж, содержащий комбинацию из эле- ментов одной или нескольких последовательностей. Формат функции: product(<Последовательность1>[,..., <ПоследовательностьN>][, repeat=1])
Примеры:
>>> from itertools import product
>>> list(product('абвг', repeat=2))
[('а', 'а'), ('а', 'б'), ('а', 'в'), ('а', 'г'), ('б', 'а'),
('б', 'б'), ('б', 'в'), ('б', 'г'), ('в', 'а'), ('в', 'б'),
('в', 'в'), ('в', 'г'), ('г', 'а'), ('г', 'б'), ('г', 'в'),
('г', 'г')]
>>> ["".join(i) for i in product('аб', 'вг', repeat=1)]
['ав', 'аг', 'бв', 'бг']
>>> ["".join(i) for i in product('аб', 'вг', repeat=2)]
['авав', 'аваг', 'авбв', 'авбг', 'агав', 'агаг', 'агбв',
'агбг', 'бвав', 'бваг', 'бвбв', 'бвбг', 'бгав', 'бгаг',
'бгбв', 'бгбг']
Глава 8. Списки, кортежи, множества и диапазоны
171 8.17.3. Фильтрация элементов последовательности
Для фильтрации элементов последовательности предназначены следующие функции:
filterfalse(<Функция>, <Последовательность>
) — возвращает элементы последователь- ности (по одному на каждой итерации), для которых функция, указанная в первом пара- метре, вернет значение
False
:
>>> import itertools
>>> def func(x): return x > 3
>>> list(itertools.filterfalse(func, [4, 5, 6, 0, 7, 2, 3]))
[0, 2, 3]
>>> list(filter(func, [4, 5, 6, 0, 7, 2, 3]))
[4, 5, 6, 7]
Если в первом параметре вместо названия функции указать значение
None
, то каждый элемент последовательности будет проверен на соответствие значению
False
. Если эле- мент в логическом контексте возвращает значение
True
, то он не войдет в возвращаемый результат:
>>> list(itertools.filterfalse(None, [0, 5, 6, 0, 7, 0, 3]))
[0, 0, 0]
>>> list(filter(None, [0, 5, 6, 0, 7, 0, 3]))
[5, 6, 7, 3]
dropwhile(<Функция>, <Последовательность>)
— возвращает элементы последователь- ности (по одному на каждой итерации), начиная с элемента, для которого функция, ука- занная в первом параметре, вернет значение
False
:
>>> def func(x): return x > 3
>>> list(itertools.dropwhile(func, [4, 5, 6, 0, 7, 2, 3]))
[0, 7, 2, 3]
>>> list(itertools.dropwhile(func, [4, 5, 6, 7, 8]))
[]
>>> list(itertools.dropwhile(func, [1, 2, 4, 5, 6, 7, 8]))
[1, 2, 4, 5, 6, 7, 8]
takewhile(<Функция>, <Последовательность>)
— возвращает элементы последователь- ности (по одному на каждой итерации), пока не встретится элемент, для которого функ- ция, указанная в первом параметре, вернет значение
False
:
>>> def func(x): return x > 3
>>> list(itertools.takewhile(func, [4, 5, 6, 0, 7, 2, 3]))
[4, 5, 6]
>>> list(itertools.takewhile(func, [4, 5, 6, 7, 8]))
[4, 5, 6, 7, 8]
>>> list(itertools.takewhile(func, [1, 2, 4, 5, 6, 7, 8]))
[]
compress()
— производит фильтрацию последовательности, указанной в первом пара- метре. Элемент возвращается, только если соответствующий элемент (с таким же индек- сом) из второй последовательности трактуется как истина. Сравнение заканчивается, когда достигнут конец одной из последовательностей. Формат функции:
172
Часть I. Основы языка Python compress(<Фильтруемая последовательность>,
<Последовательность логических значений>)
Примеры:
>>> list(itertools.compress('абвгде', [1, 0, 0, 0, 1, 1]))
['а', 'д', 'е']
>>> list(itertools.compress('абвгде', [True, False, True]))
['а', 'в']
8.17.4. Прочие функции
Помимо функций, которые мы рассмотрели в предыдущих подразделах, модуль itertools содержит несколько дополнительных функций:
islice()
— на каждой итерации возвращает очередной элемент последовательности.
Поддерживаются форматы: islice(<Последовательность>, <Конечная граница>) и islice(<Последовательность>, <Начальная граница>, <Конечная граница>[, <Шаг>])
Если
<Шаг>
не указан, будет использовано значение
1
Примеры:
>>> list(itertools.islice("абвгдезж", 3))
['а', 'б', 'в']
>>> list(itertools.islice("абвгдезж", 3, 6))
['г', 'д', 'е']
>>> list(itertools.islice("абвгдезж", 3, 6, 2))
['г', 'е']
starmap(<Функция>, <Последовательность>)
— формирует последовательность на осно- вании значений, возвращенных указанной функцией. Исходная последовательность должна содержать в качестве элементов кортежи — именно над элементами этих корте- жей функция и станет вычислять значения, которые войдут в генерируемую последова- тельность. Примеры суммирования значений:
>>> import itertools
>>> def func1(x, y): return x + y
>>> list(itertools.starmap(func1, [(1, 2), (4, 5), (6, 7)]))
[3, 9, 13]
>>> def func2(x, y, z): return x + y + z
>>> list(itertools.starmap(func2, [(1, 2, 3), (4, 5, 6)]))
[6, 15]
zip_longest()
— на каждой итерации возвращает кортеж, содержащий элементы после- довательностей, которые расположены на одинаковом смещении. Если последователь- ности имеют разное количество элементов, вместо отсутствующего элемента вставляет- ся объект, указанный в параметре fillvalue
. Формат функции: zip_longest(<Последовательность1>[, ..., <ПоследовательностьN>]
[, fillvalue=None])
Глава 8. Списки, кортежи, множества и диапазоны
173
Примеры:
>>> list(itertools.zip_longest([1, 2, 3], [4, 5, 6]))
[(1, 4), (2, 5), (3, 6)]
>>> list(itertools.zip_longest([1, 2, 3], [4]))
[(1, 4), (2, None), (3, None)]
>>> list(itertools.zip_longest([1, 2, 3], [4], fillvalue=0))
[(1, 4), (2, 0), (3, 0)]
>>> list(zip([1, 2, 3], [4]))
[(1, 4)]
accumulate(<Последовательность>[, <функция>])
— на каждой итерации возвращает результат, полученный выполнением определенного действия над текущим элементом и результатом, полученным на предыдущей итерации. Выполняемая операция задается параметром
<Функция>
, а если он не указан, выполняется операция сложения. Функция, выполняющая операцию, должна принимать два параметра и возвращать результат. На первой итерации всегда возвращается первый элемент переданной последовательности:
>>> # Выполняем сложение
>>> list(itertools.accumulate([1, 2, 3, 4, 5, 6]))
[1, 3, 6, 10, 15, 21]
>>> # [1, 1+2, 3+3, 6+4, 10+5, 15+6]
>>> # Выполняем умножение
>>> def func(x, y): return x * y
>>> list(itertools.accumulate([1, 2, 3, 4, 5, 6], func))
[1, 2, 6, 24, 120, 720]
>>> # [1, 1*2, 2*3, 6*4, 24*5, 120*6]
chain()
— на каждой итерации возвращает элементы сначала из первой последователь- ности, затем из второй и т. д. Формат функции: chain(<Последовательность1>[, ..., <ПоследовательностьN>])
Примеры:
>>> arr1, arr2, arr3 = [1, 2, 3], [4, 5], [6, 7, 8, 9]
>>> list(itertools.chain(arr1, arr2, arr3))
[1, 2, 3, 4, 5, 6, 7, 8, 9]
>>> list(itertools.chain("abc", "defg", "hij"))
['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j']
>>> list(itertools.chain("abc", ["defg", "hij"]))
['a', 'b', 'c', 'defg', 'hij']
chain.from_iterable(<Последовательность>)
— аналогична функции chain()
, но прини- мает одну последовательность, каждый элемент которой считается отдельной последо- вательностью:
>>> list(itertools.chain.from_iterable(["abc", "defg", "hij"]))
['a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j']
tee(<Последовательность>[, <Количество>])
— возвращает кортеж, содержащий не- сколько одинаковых итераторов для последовательности. Если второй параметр не ука- зан, то возвращается кортеж из двух итераторов:
174
Часть I. Основы языка Python
>>> arr = [1, 2, 3]
>>> itertools.tee(arr)
(1>2>
1 ... 11 12 13 14 15 16 17 18 ... 83
>>> itertools.tee(arr, 3)
(
>>> list(itertools.tee(arr)[0])
[1, 2, 3]
>>> list(itertools.tee(arr)[1])
[1, 2, 3]
ГЛ А В А
9
Словари
Словари — это наборы объектов, доступ к которым осуществляется не по индексу, а по ключу. В качестве ключа можно указать неизменяемый объект, например: число, строку или кортеж. Элементы словаря могут содержать объекты произвольного типа данных и иметь неограниченную степень вложенности. Следует также заметить, что элементы в сло- варях располагаются в произвольном порядке. Чтобы получить элемент, необходимо ука- зать ключ, который использовался при сохранении значения.
Словари относятся к отображениям, а не к последовательностям. По этой причине функции, предназначенные для работы с последовательностями, а также операции извлечения среза, конкатенации, повторения и др., к словарям не применимы. Равно как и списки, словари относятся к изменяемым типам данных. Иными словами, мы можем не только получить значение по ключу, но и изменить его.
9.1. Создание словаря
Создать словарь можно следующими способами:
с помощью функции dict()
. Форматы функции: dict(<Ключ1>=<Значение1>[, ..., <КлючN>=<ЗначениеN>]) dict(<Словарь>) dict(<Список кортежей с двумя элементами (Ключ, Значение)>) dict(<Список списков с двумя элементами [Ключ, Значение]>)
Если параметры не указаны, создается пустой словарь:
>>> d = dict(); d # Создаем пустой словарь
{}
>>> d = dict(a=1, b=2); d
{'a': 1, 'b': 2}
>>> d = dict({"a": 1, "b": 2}); d # Словарь
{'a': 1, 'b': 2}
>>> d = dict([("a", 1), ("b", 2)]); d # Список кортежей
{'a': 1, 'b': 2}
>>> d = dict([["a", 1], ["b", 2]]); d # Список списков
{'a': 1, 'b': 2}
176
Часть I. Основы языка Python
Объединить два списка в список кортежей позволяет функция zip()
:
>>> k = ["a", "b"] # Список с ключами
>>> v = [1, 2] # Список со значениями
>>> list(zip(k, v)) # Создание списка кортежей
[('a', 1), ('b', 2)]
>>> d = dict(zip(k, v)); d # Создание словаря
{'a': 1, 'b': 2}
указав все элементы словаря внутри фигурных скобок — это наиболее часто используе- мый способ создания словаря. Между ключом и значением ставится двоеточие, а пары
«ключ/значение» записываются через запятую:
>>> d = {}; d # Создание пустого словаря
{}
>>> d = { "a": 1, "b": 2 }; d
{'a': 1, 'b': 2}
заполнив словарь поэлементно. В этом случае ключ указывается внутри квадратных скобок:
>>> d = {} # Создаем пустой словарь
>>> d["a"] = 1 # Добавляем элемент1 (ключ "a")
>>> d["b"] = 2 # Добавляем элемент2 (ключ "b")
>>> d
{'a': 1, 'b': 2}
с помощью метода dict.fromkeys(<Последовательность>[, <Значение>])
. Метод создает новый словарь, ключами которого станут элементы последовательности, переданной первым параметром, а их значениями — величина, переданная вторым параметром. Если второй параметр не указан, элементы словаря получат в качестве значения
None
:
>>> d = dict.fromkeys(["a", "b", "c"])
>>> d
{'a': None, 'c': None, 'b': None}
>>> d = dict.fromkeys(["a", "b", "c"], 0) # Указан список
>>> d
{'a': 0, 'c': 0, 'b': 0}
>>> d = dict.fromkeys(("a", "b", "c"), 0) # Указан кортеж
>>> d
{'a': 0, 'c': 0, 'b': 0}
При создании словаря в переменной сохраняется ссылка на объект, а не сам объект. Это обязательно следует учитывать при групповом присваивании. Групповое присваивание можно использовать для чисел и строк, но для списков и словарей этого делать нельзя. Рас- смотрим пример:
>>> d1 = d2 = { "a": 1, "b": 2 } # Якобы создали два объекта
>>> d2["b"] = 10
>>> d1, d2 # Изменилось значение в двух переменных !!!
({'a': 1, 'b': 10}, {'a': 1, 'b': 10})
Сразу видно, что изменение значения в переменной d2
привело также к изменению значе- ния в переменной d1
, т. е. обе переменные ссылаются на один и тот же объект. Чтобы полу- чить два объекта, необходимо производить раздельное присваивание:
Глава 9. Словари
177
>>> d1, d2 = { "a": 1, "b": 2 }, { "a": 1, "b": 2 }
>>> d2["b"] = 10
>>> d1, d2
({'a': 1, 'b': 2}, {'a': 1, 'b': 10})
Создать поверхностную копию словаря позволяет функция dict()
:
>>> d1 = { "a": 1, "b": 2 } # Создаем словарь
>>> d2 = dict(d1) # Создаем поверхностную копию
>>> d1 is d2 # Оператор показывает, что это разные объекты
False
>>> d2["b"] = 10
>>> d1, d2 # Изменилось только значение в переменной d2
({'a': 1, 'b': 2}, {'a': 1, 'b': 10})
Также можно воспользоваться методом copy()
:
>>> d1 = { "a": 1, "b": 2 } # Создаем словарь
>>> d2 = d1.copy() # Создаем поверхностную копию
>>> d1 is d2 # Оператор показывает, что это разные объекты
False
>>> d2["b"] = 10
>>> d1, d2 # Изменилось только значение в переменной d2
({'a': 1, 'b': 2}, {'a': 1, 'b': 10})
Чтобы создать полную копию словаря, следует воспользоваться функцией deepcopy()
из модуля copy
:
>>> d1 = { "a": 1, "b": [20, 30, 40] }
>>> d2 = dict(d1) # Создаем поверхностную копию
>>> d2["b"][0] = "test"
>>> d1, d2 # Изменились значения в двух переменных!!!
({'a': 1, 'b': ['test', 30, 40]}, {'a': 1, 'b': ['test', 30, 40]})
>>> import copy
>>> d3 = copy.deepcopy(d1) # Создаем полную копию
>>> d3["b"][1] = 800
>>> d1, d3 # Изменилось значение только в переменной d3
({'a': 1, 'b': ['test', 30, 40]}, {'a': 1, 'b': ['test', 800, 40]})
9.2. Операции над словарями
Обращение к элементам словаря осуществляется с помощью квадратных скобок, в которых указывается ключ. В качестве ключа можно указать неизменяемый объект, например: чис- ло, строку или кортеж.
Выведем все элементы словаря:
>>> d = { 1: "int", "a": "str", (1, 2): "tuple" }
>>> d[1], d["a"], d[(1, 2)]
('int', 'str', 'tuple')
Если элемент, соответствующий указанному ключу, отсутствует в словаре, возбуждается исключение
KeyError
:
178
Часть I. Основы языка Python
>>> d = { "a": 1, "b": 2 }
>>> d["c"] # Обращение к несуществующему элементу
Traceback (most recent call last):
File "
", line 1, in
KeyError: 'c'
Проверить существование ключа в словаре можно с помощью оператора in
. Если ключ найден, возвращается значение
True
, в противном случае —
False
:
>>> d = { "a": 1, "b": 2 }
>>> "a" in d # Ключ существует
True
>>> "c" in d # Ключ не существует
False
Проверить, отсутствует ли какой-либо ключ в словаре, позволит оператор not in
. Если ключ отсутствует, возвращается
True
, иначе —
False
:
>>> d = { "a": 1, "b": 2 }
>>> "c" not in d # Ключ не существует
True
>>> "a" not in d # Ключ существует
False
Метод get(<Ключ>[, <Значение по умолчанию>])
позволяет избежать возбуждения исклю- чения
KeyError при отсутствии в словаре указанного ключа. Если ключ присутствует в сло- варе, метод возвращает значение, соответствующее этому ключу. Если ключ отсутствует, возвращается
None или значение, указанное во втором параметре:
>>> d = { "a": 1, "b": 2 }
>>> d.get("a"), d.get("c"), d.get("c", 800)
(1, None, 800)
Кроме того, можно воспользоваться методом setdefault(<Ключ>[, <Значение по умолча- нию>])
. Если ключ присутствует в словаре, метод возвращает значение, соответствующее этому ключу. Если ключ отсутствует, в словаре создается новый элемент со значением, ука- занным во втором параметре. Если второй параметр не указан, значением нового элемента будет
None
:
>>> d = { "a": 1, "b": 2 }
>>> d.setdefault("a"), d.setdefault("c"), d.setdefault("d", 0)
(1, None, 0)
>>> d
{'a': 1, 'c': None, 'b': 2, 'd': 0}
Так как словари относятся к изменяемым типам данных, мы можем изменить элемент по ключу. Если элемент с указанным ключом отсутствует в словаре, он будет создан:
>>> d = { "a": 1, "b": 2 }
>>> d["a"] = 800 # Изменение элемента по ключу
>>> d["c"] = "string" # Будет добавлен новый элемент
>>> d
{'a': 800, 'c': 'string', 'b': 2}
Глава 9. Словари
179
Получить количество ключей в словаре позволяет функция len()
:
>>> d = { "a": 1, "b": 2 }
>>> len(d) # Получаем количество ключей в словаре
2
Удалить элемент из словаря можно с помощью оператора del
:
>>> d = { "a": 1, "b": 2 }
>>> del d["b"]; d # Удаляем элемент с ключом "b" и выводим словарь
{'a': 1}
9.3. Перебор элементов словаря
Перебрать все элементы словаря можно с помощью цикла for
, хотя словари и не являются последовательностями. Для примера выведем элементы словаря двумя способами. Первый способ использует метод keys()
, возвращающий объект с ключами словаря. Во втором слу- чае мы просто указываем словарь в качестве параметра. На каждой итерации цикла будет возвращаться ключ, с помощью которого внутри цикла можно получить значение, соответ- ствующее этому ключу (листинг 9.1).
Листинг 9.1. Перебор элементов словаря d = {"x": 1, "y": 2, "z": 3} for key in d.keys(): # Использование метода keys() print("({0} => {1})".format(key, d[key]), end=" ")
# Выведет: (y => 2) (x => 1) (z => 3) print() # Вставляем символ перевода строки for key in d: # Словари также поддерживают итерации print("({0} => {1})".format(key, d[key]), end=" ")
# Выведет: (y => 2) (x => 1) (z => 3)
Поскольку словари являются неупорядоченными структурами, элементы словаря выводятся в произвольном порядке. Чтобы вывести элементы с сортировкой по ключам, следует полу- чить список ключей, а затем воспользоваться методом sort()
(листинг 9.2).
Листинг 9.2. Упорядоченный вывод элементов словаря с помощью метода sort() d = {"x": 1, "y": 2, "z": 3} k = list(d.keys()) # Получаем список ключей k.sort() # Сортируем список ключей for key in k: print("({0} => {1})".format(key, d[key]), end=" ")
# Выведет: (x => 1) (y => 2) (z => 3)
Для сортировки ключей вместо метода sort()
можно воспользоваться функцией sorted()
(листинг 9.3).
180
Часть I. Основы языка Python
Листинг 9.3. Упорядоченный вывод элементов словаря с помощью функции sorted() d = {"x": 1, "y": 2, "z": 3} for key in sorted(d.keys()): print("({0} => {1})".format(key, d[key]), end=" ")
# Выведет: (x => 1) (y => 2) (z => 3)
Так как на каждой итерации возвращается ключ словаря, функции sorted()
можно сразу передать объект словаря, а не результат выполнения метода keys()
(листинг 9.4).
Листинг 9.4. Упорядоченный вывод элементов словаря с помощью функции sorted() d = {"x": 1, "y": 2, "z": 3} for key in sorted(d): print("({0} => {1})".format(key, d[key]), end=" ")
# Выведет: (x => 1) (y => 2) (z => 3)
9.4. Методы для работы со словарями
Для работы со словарями предназначены следующие методы:
keys()
— возвращает объект dict_keys
, содержащий все ключи словаря. Этот объект поддерживает итерации, а также операции над множествами:
>>> d1, d2 = { "a": 1, "b": 2 }, { "a": 3, "c": 4, "d": 5 }
>>> d1.keys(), d2.keys() # Получаем объект dict_keys
(dict_keys(['a', 'b']), dict_keys(['a', 'c', 'd']))
>>> list(d1.keys()), list(d2.keys()) # Получаем список ключей
(['a', 'b'], ['a', 'c', 'd'])
>>> for k in d1.keys(): print(k, end=" ") a b
>>> d1.keys() | d2.keys() # Объединение
{'a', 'c', 'b', 'd'}
>>> d1.keys() — d2.keys() # Разница
{'b'}
>>> d2.keys() — d1.keys() # Разница
{'c', 'd'}
>>> d1.keys() & d2.keys() # Одинаковые ключи
{'a'}
>>> d1.keys() ^ d2.keys() # Уникальные ключи
{'c', 'b', 'd'}
values()
— возвращает объект dict_values
, содержащий все значения словаря. Этот объект поддерживает итерации:
>>> d = { "a": 1, "b": 2 }
>>> d.values() # Получаем объект dict_values dict_values([1, 2])
>>> list(d.values()) # Получаем список значений
[1, 2]
Глава 9. Словари
181
>>> [ v for v in d.values() ]
[1, 2]
items()
— возвращает объект dict_items
, содержащий все ключи и значения в виде кор- тежей. Этот объект поддерживает итерации:
>>> d = { "a": 1, "b": 2 }
>>> d.items() # Получаем объект dict_items dict_items([('a', 1), ('b', 2)])
>>> list(d.items()) # Получаем список кортежей
[('a', 1), ('b', 2)]
<Ключ> in <Словарь>
— проверяет существование указанного ключа в словаре. Если ключ найден, возвращается значение
True
, в противном случае —
False
:
>>> d = { "a": 1, "b": 2 }
>>> "a" in d # Ключ существует
True
>>> "c" in d # Ключ не существует
False
<Ключ> not in <Словарь>
— проверяет отсутствие указанного ключа в словаре. Если такового ключа нет, возвращается значение
True
, в противном случае —
False
:
>>> d = { "a": 1, "b": 2 }
>>> "c" not in d # Ключ не существует
True
>>> "a" not in d # Ключ существует
False
get(<Ключ>[, <Значение по умолчанию>])
— если ключ присутствует в словаре, метод возвращает значение, соответствующее этому ключу. Если ключ отсутствует, возвраща- ется
None или значение, указанное во втором параметре:
>>> d = { "a": 1, "b": 2 }
>>> d.get("a"), d.get("c"), d.get("c", 800)
(1, None, 800)
setdefault(<Ключ>[, <Значение по умолчанию>])
— если ключ присутствует в словаре, метод возвращает значение, соответствующее этому ключу. Если ключ отсутствует, в словаре создается новый элемент со значением, указанным во втором параметре. Если второй параметр не указан, значением нового элемента будет
None
:
>>> d = { "a": 1, "b": 2 }
>>> d.setdefault("a"),d.setdefault("c"),d.setdefault("d", 0)
(1, None, 0)
>>> d
{'a': 1, 'c': None, 'b': 2, 'd': 0}
pop(<Ключ>[, <Значение по умолчанию>])
— удаляет элемент с указанным ключом и возвращает его значение. Если ключ отсутствует, возвращается значение из второго параметра. Если ключ отсутствует и второй параметр не указан, возбуждается исключе- ние
KeyError
:
>>> d = { "a": 1, "b": 2, "c": 3 }
>>> d.pop("a"), d.pop("n", 0)
(1, 0)
182
Часть I. Основы языка Python
>>> d.pop("n") # Ключ отсутствует и нет второго параметра
Traceback (most recent call last):
File "
", line 1, in
KeyError: 'n'
>>> d
{'c': 3, 'b': 2}
popitem()
— удаляет произвольный элемент и возвращает кортеж из ключа и значения.
Если словарь пустой, возбуждается исключение
KeyError
:
>>> d = { "a": 1, "b": 2 }
>>> d.popitem() # Удаляем произвольный элемент
('a', 1)
>>> d.popitem() # Удаляем произвольный элемент
('b', 2)
>>> d.popitem() # Словарь пустой. Возбуждается исключение
Traceback (most recent call last):
File "
", line 1, in
KeyError: 'popitem(): dictionary is empty'
clear()
— удаляет все элементы словаря. Метод ничего не возвращает в качестве значе- ния:
>>> d = { "a": 1, "b": 2 }
>>> d.clear() # Удаляем все элементы
>>> d # Словарь теперь пустой
{}
update()
— добавляет элементы в словарь. Метод изменяет текущий словарь и ничего не возвращает. Форматы метода: update(<Ключ1>=<Значение1>[, ..., <КлючN>=<ЗначениеN>]) update(<Словарь>) update(<Список кортежей с двумя элементами>) update(<Список списков с двумя элементами>)
Если элемент с указанным ключом уже присутствует в словаре, то его значение будет перезаписано.
Примеры:
>>> d = { "a": 1, "b": 2 }
>>> d.update(c=3, d=4)
>>> d
{'a': 1, 'c': 3, 'b': 2, 'd': 4}
>>> d.update({"c": 10, "d": 20}) # Словарь
>>> d # Значения элементов перезаписаны
{'a': 1, 'c': 10, 'b': 2, 'd': 20}
>>> d.update([("d", 80), ("e", 6)]) # Список кортежей
>>> d
{'a': 1, 'c': 10, 'b': 2, 'e': 6, 'd': 80}
Глава 9. Словари
183
>>> d.update([["a", "str"], ["i", "t"]]) # Список списков
>>> d
{'a': 'str', 'c': 10, 'b': 2, 'e': 6, 'd': 80, 'i': 't'}
copy()
— создает поверхностную копию словаря:
>>> d1 = { "a": 1, "b": [10, 20] }
>>> d2 = d1.copy() # Создаем поверхностную копию
>>> d1 is d2 # Это разные объекты
False
>>> d2["a"] = 800 # Изменяем значение
>>> d1, d2 # Изменилось значение только в d2
({'a': 1, 'b': [10, 20]}, {'a': 800, 'b': [10, 20]})
>>> d2["b"][0] = "new" # Изменяем значение вложенного списка
>>> d1, d2 # Изменились значения и в d1, и в d2!!!
({'a': 1, 'b': ['new', 20]}, {'a': 800, 'b': ['new', 20]})
Чтобы создать полную копию словаря, следует воспользоваться функцией deepcopy()
из модуля copy
9.5. Генераторы словарей
Помимо генераторов списков, язык Python 3 поддерживает генераторы словарей. Синтаксис генераторов словарей похож на синтаксис генераторов списков, но имеет два различия:
выражение заключается в фигурные скобки, а не в квадратные;
внутри выражения перед циклом for указываются два значения через двоеточие, а не одно. Значение, расположенное слева от двоеточия, становится ключом, а значение, рас- положенное справа от двоеточия, — значением элемента.
Пример:
>>> keys = ["a", "b"] # Список с ключами
>>> values = [1, 2] # Список со значениями
>>> {k: v for (k, v) in zip(keys, values)}
{'a': 1, 'b': 2}
>>> {k: 0 for k in keys}
{'a': 0, 'b': 0}
Генераторы словарей могут иметь сложную структуру — например, состоять из нескольких вложенных циклов for и (или) содержать оператор ветвления if после цикла. Создадим из исходного словаря новый словарь, содержащий только элементы с четными значениями:
>>> d = { "a": 1, "b": 2, "c": 3, "d": 4 }
>>> {k: v for (k, v) in d.items() if v % 2 == 0}
{'b': 2, 'd': 4}
ГЛ А В А
10
Работа с датой и временем
Для работы с датой и временем в языке Python предназначены следующие модули:
time
— позволяет получить текущие дату и время, а также произвести их форматиро- ванный вывод;
1 ... 12 13 14 15 16 17 18 19 ... 83
datetime
— позволяет манипулировать датой и временем. Например, производить арифметические операции, сравнивать даты, выводить дату и время в различных форма- тах и др.;
calendar
— позволяет вывести календарь в виде простого текста или в HTML-формате;
timeit
— позволяет измерить время выполнения небольших фрагментов кода с целью оптимизации программы.
10.1. Получение текущих даты и времени
Получить текущие дату и время позволяют следующие функции из модуля time
:
time()
— возвращает вещественное число, представляющее количество секунд, про- шедшее с начала эпохи (обычно с 1 января 1970 г.):
>>> import time # Подключаем модуль time
>>> time.time() # Получаем количество секунд
1511273856.8787858
gmtime([<Количество секунд>])
— возвращает объект struct_time
, представляющий универсальное время (UTC). Если параметр не указан, возвращается текущее время.
Если параметр указан, время будет не текущим, а соответствующим количеству секунд, прошедших с начала эпохи:
>>> time.gmtime(0) # Начало эпохи time.struct_time(tm_year=1970, tm_mon=1, tm_mday=1, tm_hour=0, tm_min=0, tm_sec=0, tm_wday=3, tm_yday=1, tm_isdst=0)
>>> time.gmtime() # Текущая дата и время time.struct_time(tm_year=2017, tm_mon=11, tm_mday=21, tm_hour=14, tm_min=17, tm_sec=55, tm_wday=1, tm_yday=325, tm_isdst=0)
>>> time.gmtime(1511273856.0) # Дата 21-11-2017 time.struct_time(tm_year=2017, tm_mon=11, tm_mday=21, tm_hour=14, tm_min=17, tm_sec=36, tm_wday=1, tm_yday=325, tm_isdst=0)
Глава 10. Работа с датой и временем
185
Получить значение конкретного атрибута можно, указав его название или индекс внутри объекта:
>>> d = time.gmtime()
>>> d.tm_year, d[0]
(2017, 2017)
>>> tuple(d) # Преобразование в кортеж
(2017, 11, 21, 14, 19, 34, 1, 325, 0)
localtime([<Количество секунд>])
— возвращает объект struct_time
, представляющий локальное время. Если параметр не указан, возвращается текущее время. Если параметр указан, время будет не текущим, а соответствующим количеству секунд, прошедших с начала эпохи:
>>> time.localtime() # Текущая дата и время time.struct_time(tm_year=2017, tm_mon=11, tm_mday=21, tm_hour=17, tm_min=20, tm_sec=4, tm_wday=1, tm_yday=325, tm_isdst=0)
>>> time.localtime(1511273856.0) # Дата 21-11-2017 time.struct_time(tm_year=2017, tm_mon=11, tm_mday=21, tm_hour=17, tm_min=17, tm_sec=36, tm_wday=1, tm_yday=325, tm_isdst=0)
mktime(<Объект struct_time>)
— возвращает вещественное число, представляющее ко- личество секунд, прошедших с начала эпохи. В качестве параметра указывается объект struct_time или кортеж из девяти элементов. Если указанная дата некорректна, возбуж- дается исключение
OverflowError
:
>>> d = time.localtime(1511273856.0)
>>> time.mktime(d)
1511273856.0
>>> tuple(time.localtime(1511273856.0))
(2017, 11, 21, 17, 17, 36, 1, 325, 0)
>>> time.mktime((2017, 11, 21, 17, 17, 36, 1, 325, 0))
1511273856.0
>>> time.mktime((1940, 0, 31, 5, 23, 43, 5, 31, 0))
... Фрагмент опущен ...
OverflowError: mktime argument out of range
Объект struct_time
, возвращаемый функциями gmtime()
и localtime()
, содержит следую- щие атрибуты (указаны тройки вида «имя атрибута — индекс — описание»):
tm_year
—
0
— год;
tm_mon
—
1
— месяц (число от
1
до
12
);
tm_mday
—
2
— день месяца (число от
1
до
31
);
tm_hour
—
3
— час (число от
0
до
23
);
tm_min
—
4
— минуты (число от
0
до
59
);
tm_sec
—
5
— секунды (число от
0
до
59
, изредка до
61
);
tm_wday
—
6
— день недели (число от
0
для понедельника до
6
для воскресенья);
tm_yday
—
7
— количество дней, прошедшее с начала года (число от
1
до
366
);
tm_isdst
—
8
— флаг коррекции летнего времени (значения
0
,
1
или
–1
).
Выведем текущие дату и время таким образом, чтобы день недели и месяц были написаны по-русски (листинг 10.1).