В данной статье мы рассмотрим, как работают представления словарей (dictionary comprehension) в языке Python. Будет приведено много примеров, из которых мы поймем основную концепцию представления словарей в Python и как оно используется в реальных задачах.
Что такое словарь
Словарь — это встроенный в Python тип данных, в котором значения данных связаны с соответствующими ключами. Грубо говоря, это очень похоже на SQL-таблицы, сходным образом данные хранятся и во многих статистических пакетах. Словарь состоит из двух основных компонентов:
- Ключи. Они сродни колонкам в SQL-таблицах и должны быть уникальными (как и названия колонок не могут повторяться).
- Значения. Они обладают свойствами рядов в таблицах и могут повторяться.
Словари заключаются в фигурные скобки {}, а ключи отделяются от значений двоеточием.
Синтаксис словарей
Словари в языке Python выглядят следующим образом:
d = {'a': [1,2], 'b': [3,4], 'c': [5,6]}
Здесь 'a', 'b' и 'c' являются ключами, а списки после двоеточия — значениями (данными). Чтобы извлечь ключи, данные и структуру словаря, можно воспользоваться следующими командами:
d.keys() # 'a', 'b', 'c' - это ключи d.values() # [1, 2], [3, 4], [5, 6] - это данные d.items()
Как в R или SAS, в Python мы можем создать из нашего словаря датафрейм, воспользовавшись библиотекой pandas.
import pandas as pd pd.DataFrame(data = d)
В результате получим следующую таблицу:
a b c 0 1 3 5 1 2 4 6
Что такое представление словарей
Подобно представлению списков, представление словарей позволяет нам перебирать словарь в цикле for при помощи всего одной строчки кода.
Представления списков и словарей являются частью функционального программирования. Главная цель этой конструкции — сделать код более читаемым и создавать словари и списки прозрачным образом, не используя в явном виде полноценный цикл.
Разница между представлением списков и представлением словарей, как не сложно догадаться, состоит в том, что первая конструкция создает списки, а вторая соответственно словари. Синтаксис также слегка различается, так как словари в Python используют квадратные скобки [], а словари — фигурные {}.
Синтаксис представления словарей
{key: value for (key, value) in iterable}
Здесь iterable это любой объект языка Python, по которому можно производить итерацию при помощи цикла. Например, это могут быть списки, кортежи или строки. Рассмотрим следующий код:
keys = ['a', 'b', 'c']
values = [1, 2, 3]
{i: j for (i, j) in zip(keys, values)}
Этот код создает словарь: {'a': 1, 'b': 2, 'c': 3}. Также заметим, что точно такой же словарь можно создать при помощи встроенной функции dict следующим образом: dict(zip(keys, values)).
Представление словарей также можно использовать и с одной внутренней переменной. В следующем примере мы используем переменную i, чтобы создать словарь с ключами i и значениями i**2.
Чтобы увидеть разницу между представлением словарей и обычным применением цикла, в таблице ниже приведены оба варианта.
| Представление словарей | Цикл for |
d = {i: i**2 for i in range(5)}
|
d = {}
for i in range(5):
d[i] = i**2
print(d)
|
Здесь функция range(5) возвращает последовательность от 0 до 4 включительно (5 не входит).
Результат:
{0: 0, 1: 1, 2: 4, 3: 9, 4: 16}
Функция d.keys() возвращает все ключи данного словаря d (в виде списка), а функция d.values() соответственно значения.
d.keys() # возвращает [0, 1, 2, 3, 4] d.values() # возвращает [0, 1, 4, 9, 16]
Создание словаря с алфавитными ключами
Допустим, что мы хотим создать словарь, где ключами будут буквы латинского алфавита от ‘a’ до ‘e’, а значениями — числа от 0 до 4 включительно. Функция string.ascii_lowercase[:5] возвращает в качестве результата строку 'abcde'.
import string
{i: j for (i, j) in zip(string.ascii_lowercase[:5], range(5))
Данный код создаст словарь следующего вида:
{'a': 0, 'b': 1, 'c': 2, 'd': 3, 'e': 4}
Создание нового словаря из уже существующего
Функция dic.items() возвращает словарь целиком, с ключами и соответствующими значениями. В следующем примере мы умножаем значения существующего словаря на 2 и создаем с этими измененными значениями новый словарь в переменной new_dic.
dic = {'a': 1, 'b': 2, 'c': 3, 'd': 4}
new_dic = {i: j * 2 for i, j in dic.items()}
new_dic
Результат:
{'a': 2, 'b': 4, 'c': 6, 'd': 8}
Использование оператора if в представлении словарей
В данном примере мы применим условный оператор if и отберем все значения больше 2.
dic = {'a': 1, 'b': 2, 'c': 3, 'd': 4}
{i: j * 2 for (i, j) in dic.items() if j > 2}
Результат:
{'c': 6, 'd': 8}
Конструкция if - else в представлении словарей
Так же как и в представлении списков, конструкцию if - else можно использовать в представлении словарей. В следующем примере мы проверяем четность числа и ставим данному ключу в соответствие значение либо ‘odd’ (нечетное), либо ‘even’ (четное).
dic = {'a': 1, 'b': 2, 'c': 3, 'd': 4}
{i: ('even' if j % 2 == 0 else 'odd') for (i, j) in dic.items()}
Результат:
{'a': 'odd', 'b': 'even', 'c': 'odd', 'd': 'even'}
Использование функции enumerate() в представлении словарей
Функция enumerate() может принимать на вход список, кортеж или строку и возвращает каждый элемент последовательности и его индекс в виде кортежей из двух элементов, первым идет индекс, вторым сам элемент. Вот пример работы этой функции:
list(enumerate(['a', 'b', 'c']))
Обернув функцию enumerate() в функцию list(), мы получаем в результате список кортежей:
[(0, 'a'), (1, 'b'), (2, 'c')]
При помощи этой функции мы можем создать словарь, где элементы списка будут ключами, а индексы значениями словаря. (Прим. переводчика: а можем и наоборот).
mylist = ['a', 'b', 'c']
{j: i for (i, j) in enumerate(mylist)}
Результат:
{'a': 0, 'b': 1, 'c': 2}
Удаление выбранных элементов из словаря
Допустим, у нас есть словарь, который в качестве ключей содержит в себе определенные имена городов, имеющие некоторые числовые значения, и мы хотим удалить несколько городов (скажем, Дели и Лондон) вместе с их значениями. В нашем примере переменная i отвечает за ключи словаря, а выражение d[i] вычисляет значение по этому ключу. Например, d['Mumbai'] возвратит 221.
d = {'Delhi': 121, 'Mumbai': 221, 'New York': 302, 'London': 250}
{i: d[i] for i in d.keys() - {'Delhi', 'London'}}
В результате в словаре останется два элемента:
{'Mumbai': 221, 'New York': 302}

