Python 3. Словари

В этой статье разбираем Словари в языке программирования Python 3, узнаем какими свойствами обладают словари и как можно с ними работать. Примеры в этой статье выполнены на версии: Python 3.14.3.

🕒 5 мин.

Свойства словарей

Я уже писал про последовательности и множества в Python 3. Словарь — это одно из множеств в Python, то есть словарь хранит множество значений. Словарь действительно похож на обычный словарь:

  • в словаре: слово → значение,
  • в Python: ключ → значение.

Стоит запомнить что словарь — это не упорядоченное множество объектов, то есть элементы словаря не индексируются и по индексу к ним не обратиться. Срезы словарей тоже не получится сделать. Хотя стоит упомянуть, что начиная с Python 3.7 словари сохраняют порядок добавления элементов. Однако при написании алгоритмов обычно не стоит полагаться на порядок словаря.

Словари напоминают json:

#JSON
{
  "name": "Alex",
  "date": 12.05.1985,
  "city": "Moscow"
}

#Python
my_dict = {
    "name": "Alex",
    "date": 12.05.1985,
    "city": "Moscow"
}

Кстати, ключи не обязаны всегда быть строками, можно использовать и числа.

А ещё словари поддерживают вложенность, так внутри словаря может быть другой словарь или список.

config = {
    "port": 22,
    "user": "root",
    "network" : {
        'ip' : '192.168.1.10', 
        'gateway' : '192.168.1.1'
        }
}

Создание словаря

Создаётся словарь с помощью фигурных скобок, а получить значение мы можем по ключу.

# пустой словарь
users = {}

# заполненный словарь
users = {'user1' : 'Vasily', 'user2' : 'Dmitry'}

print(users)
print(users['user1'])

# Выполнение:
{'user1': 'Vasily', 'user2': 'Dmitry'}
Vasily

Где можно использовать словари

Я не являюсь разработчиком, скорее Linux админ или DevOps инженер. Но часто использую Python в своей работе. Так вот, в моём случае Словари часто применяются для хранения настроек, например:

config = {
    "host": "192.168.1.10",
    "port": 22,
    "user": "root"
}

Словари также можно использовать для:

  • парсинга JSON/YAML;
  • кэширования;
  • агрегации и группировки данных.

Количество элементов в словаре

С помощью функции len(), можем узнать количество элементов в словаре:

config = {
    "host": "192.168.1.10",
    "port": 22,
    "user": "root"
}

print(len(config))

# Выполнение:
3

Вывод значения по его ключу (метод get)

Мы можем по ключу получить значение элемента. Вот первый, и не совсем оптимальный способ:

config = {
    "host": "192.168.1.10",
    "port": 22,
    "user": "root"
}

print(config["host"])

# Выполнение:
192.168.1.10

Он не оптимальный, потому что, если в словаре не окажется такого ключа, то программа вылетит с ошибкой:

config = {
    "host": "192.168.1.10",
    "port": 22,
    "user": "root"
}

print(config["ip"])

# Выполнение:
Traceback (most recent call last):
  File "first_dict.py", line 7, in <module>
    print(config["ip"])
          ~~~~~~^^^^^^
KeyError: 'ip'

Чтобы избежать ошибки, лучше извлекать данные из словаря с помощью метода get:

config = {
    "host": "192.168.1.10",
    "port": 22,
    "user": "root"
}

print(config.get('ip'))

# Выполнение:
None

Метод get позволяет указать значение по умолчанию, оно будет выводиться вместо None, если ключ отсутствует:

config = {
    "host": "192.168.1.10",
    "port": 22,
    "user": "root"
}

print(config.get('ip', 'no key: ip'))

# Выполнение:
no key: ip

Получение всех ключей и значений

Можно вывести все ключи с помощью метода keys(), или все значения с помощью метода values(). Или можно вывести кортежи в виде пар «ключ : значение», с помощью метода items():

config = {
    "host": "192.168.1.10",
    "port": 22,
    "user": "root"
}

print(config.keys())
print(config.values())
print(config.items())

# Выполнение:
dict_keys(['host', 'port', 'user'])
dict_values(['192.168.1.10', 22, 'root'])
dict_items([('host', '192.168.1.10'), ('port', 22), ('user', 'root')])

Преобразуя вывод items() в список, получим список кортежей. К полученному списку кортежей можно обращаться по индексу.

config = {
    "host": "192.168.1.10",
    "port": 22,
    "user": "root"
}

print(list(config.items()))
print(list(config.items())[0])
print(list(config.items())[0][1])

# Выполнение:
[('host', '192.168.1.10'), ('port', 22), ('user', 'root')]
('host', '192.168.1.10')
192.168.1.10

Добавление или обновление элементов

Добавить элемент в словарь можно так:

config = {
    "host": "192.168.1.10",
    "port": 22,
    "user": "root"
}

config['hostname'] = 'web-server-01'
print(config)

# Выполнение:
{'host': '192.168.1.10', 'port': 22, 'user': 'root', 'hostname': 'web-server-01'}

Кстати, точно также, мы можем изменить текущее значение элемента, если такой ключ уже существует в словаре.

config = {
    "host": "192.168.1.10",
    "port": 22,
    "user": "root"
}

config['host'] = '192.168.1.11'
print(config)

# Выполнение:
{'host': '192.168.1.11', 'port': 22, 'user': 'root'}

Удаление элемента из словаря (метод pop)

Удалить элемент из словаря можно с помощью метода pop():

config = {
    "host": "192.168.1.10",
    "port": 22,
    "user": "root"
}

config.pop('user')
print(config)

# Выполнение:
{'host': '192.168.1.10', 'port': 22}

А чтобы не возникла ошибка, если удаляемого ключа нет в словаре, можно методу pop() задать дополнительный параметр None:

config = {
    "host": "192.168.1.10",
    "port": 22,
    "user": "root"
}

config.pop('ip', None)
print(config)

# Выполнение:
{'host': '192.168.1.10', 'port': 22, 'user': 'root'}

Копирование словарей

Так как словарь это изменяемый объект, нужно быть аккуратным с присвоением двум переменным одного словаря:

config = {
    "host": "192.168.1.10",
    "port": 22,
    "user": "root"
}

config2 = config

config2['host'] = '192.168.1.11'

print(config)
print(config2)

# Выполнение:
{'host': '192.168.1.11', 'port': 22, 'user': 'root'}
{'host': '192.168.1.11', 'port': 22, 'user': 'root'}
  • Обратите внимание, мы редактируем config2, но вместе с этим редактируется и config.

Чтобы этого избежать, словарь нужно копировать с помощью метода copy():

config = {
    "host": "192.168.1.10",
    "port": 22,
    "user": "root"
}

config2 = config.copy()
config2['host'] = '192.168.1.11'
print(config)
print(config2)

# Выполнение:
{'host': '192.168.1.10', 'port': 22, 'user': 'root'}
{'host': '192.168.1.11', 'port': 22, 'user': 'root'}

А если у нас в словаре содержится ещё один словарь, то нужно использовать не простое копирование а глубокое копирование. Вот пример с простым копированием:

config = {
    "port": 22,
    "user": "root",
    "network" : {
        'ip' : '192.168.1.10', 
        'gateway' : '192.168.1.1'
        }
}

config2 = config.copy()

config2['network']['ip'] = '192.168.1.11'
print(config)
print(config2)

# Выполнение:
{'port': 22, 'user': 'root', 'network': {'ip': '192.168.1.11', 'gateway': '192.168.1.1'}}
{'port': 22, 'user': 'root', 'network': {'ip': '192.168.1.11', 'gateway': '192.168.1.1'}}
  • При простом копировании у нас не копируется вложенный словарь, копируется лишь ссылка на него. Поэтому когда мы изменяем вложенный словарь, то изменяем его в обоих словарях.

Чтобы этого избежать, существует глубокое копирование. Это метод deepcopy() модуля copy:

import copy

config = {
    "port": 22,
    "user": "root",
    "network" : {
        'ip' : '192.168.1.10', 
        'gateway' : '192.168.1.1'
        }
}

config2 = copy.deepcopy(config)
config2['network']['ip'] = '192.168.1.11'

print(config)
print(config2)

# Выполнение:
{'port': 22, 'user': 'root', 'network': {'ip': '192.168.1.10', 'gateway': '192.168.1.1'}}
{'port': 22, 'user': 'root', 'network': {'ip': '192.168.1.11', 'gateway': '192.168.1.1'}}

Перебор словаря

С помощью цикла for мы можем пройтись по элементам словаря.

  • Пройдёмся по ключам:
config = {
    "host": "192.168.1.10",
    "port": 22,
    "user": "root"
}

for key in config:
    print(key)

# Выполнение:
host
port
user
  • Пройдёмся по значениям:
config = {
    "host": "192.168.1.10",
    "port": 22,
    "user": "root"
}

for value in config.values():
    print(value)

# Выполнение:
192.168.1.10
22
root
  • Пройдёмся по ключам и значениям:
config = {
    "host": "192.168.1.10",
    "port": 22,
    "user": "root"
}

for key, value in config.items():
    print(key, value)

# Выполнение:
host 192.168.1.10
port 22
user root

Проверка существования ключа

Иногда требуется проверить, существует ли определённый ключ в словаре, это делается с помощью конструкции if.

config = {
    "host": "192.168.1.10",
    "port": 22,
    "user": "root"
}

if "host" in config:
    print("Ключ существует")

# Выполнение:
Ключ существует

Итог

Словари — достаточно интересный тип данных в Python. Словарь может содержать вложенные словари или списки и допускает большую вложенность. Словари — изменяемы, их можно изменять — добавляя, изменяя или удаляя элементы. Некоторые особенности словарей можете посмотреть здесь.

Пробежимся по методам ещё раз:

  • get() — получить значение;
  • keys() — список ключей;
  • values() — список значений;
  • items() — пары ключ-значение;
  • copy() — копирование словаря.

Полезные функции:

  • len(my_dict) — количество элементов в словаре;
  • copy.deepcopy(my_dict) — глубокое копирование словаря.

Если понравилась статья, подпишись на мой канал в VK или Telegram.

Мы используем cookie-файлы для наилучшего представления нашего сайта. Продолжая использовать этот сайт, вы соглашаетесь с использованием cookie-файлов.
Принять
Отказаться
Политика конфиденциальности