Дополнительные операции со словарями в Python

Материал из Викижурнал
Дополнительные операции со словарями в Python
Дополнительные операции со словарями в Python
Дополнительные операции со словарями в Python
Тематические порталы

В предыдущей статье о словарях мы уже изучили на базовом уровне, что такое словари и как с ними работать. В этой статье мы продолжим изучать, что ещё и как можно их использовать. Если есть вопросы, комментарии, то оставляйте их на странице обсуждения.

Вложенные данные

Иногда есть необходимость сохранять набор словарей в списке или список элементов в качестве значения в словаре. Этот метод называется вложения. Вы можете вкладывать набор словарей внутри списка, списка элементов внутри словаря или даже словаря внутри другого словаря. Вложенность является мощной функцией, как продемонстрируют следующие примеры.

Список из словарей

Словарь "alien_0" содержит разнообразную информацию об одном типе пришельцев в нашей воображаемой игре. Как вы можно управлять разными типами пришельцев, используя условные операторы и те знания, которыми мы уже овладели? Одним из способов является составление списка словарей с данными. Например, следующий код создает такой список из трех типов пришельцев:

alien_0 = {'color': 'green', 'points': 5}
alien_1 = {'color': 'yellow', 'points': 10}
alien_2 = {'color': 'red', 'points': 15}

aliens = [alien_0, alien_1, alien_2]

for alien in aliens:
    print(alien)

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

{'color': 'green', 'points': 5}
{'color': 'yellow', 'points': 10}
{'color': 'red', 'points': 15}

Более реалистичный пример - как создать более трех пришельцев благодаря коду, который автоматически генерирует каждого из них. В следующем примере мы используем range () для создания 30 пришельцев:

# Make an empty list for storing aliens.
aliens = []

# Make 30 green aliens.
for alien_number in range(30):
    new_alien = {'color': 'green', 'points': 5, 'speed': 'slow'}
    aliens.append(new_alien)

# Show the first 5 aliens:
for alien in aliens[:5]:
    print(alien)
print("...")

# Show how many aliens have been created.
print("Total number of aliens: " + str(len(aliens)))

Этот код начинается с пустого списка, в котором будут хранится данные пришельцев нашей воображаемой игры. range () возвращает набор чисел, который просто сообщает Python, сколько раз мы хотим, чтобы цикл повторялся. Каждый раз, когда запускается цикл, мы создаем нового пришельца и затем добавляем каждого нового пришельца в список "aliens". Далее используется срез для вывода первых пяти пришельцев, а затем выводим количество значений в списке, чтобы доказать, что показать что все данные сгенерированы автоматически:

{'speed': 'slow', 'color': 'green', 'points': 5}
{'speed': 'slow', 'color': 'green', 'points': 5}
{'speed': 'slow', 'color': 'green', 'points': 5}
{'speed': 'slow', 'color': 'green', 'points': 5}
{'speed': 'slow', 'color': 'green', 'points': 5}
...
Total number of aliens: 30

Все эти данные наших пришельцев имеют одинаковые характеристики, но Python рассматривает каждого как отдельный объект, что позволяет нам изменять каждого из них индивидуально. Как можно работать с таким набором данных? Представьте, что в одном аспекте игры есть несколько типов инопланетян, которые меняют цвет и движутся быстрее по ходу игры. Когда пришло время менять цвета, мы можем использовать цикл for и оператор if, чтобы изменить цвет инопланетян. Например, чтобы заменить первых трех пришельцев на желтых пришельцев со средней скоростью, каждая из которых имеет 10 очков, мы можем сделать это таким образом:

# Make an empty list for storing aliens.
aliens = []

# Make 30 green aliens.
for alien_number in range (0,30):
    new_alien = {'color': 'green', 'points': 5, 'speed': 'slow'}
    aliens.append(new_alien)

for alien in aliens[0:3]:
    if alien['color'] == 'green':
        alien['color'] = 'yellow'
        alien['speed'] = 'medium'
        alien['points'] = 10

# Show the first 5 aliens:
for alien in aliens[0:5]:
    print(alien)
print("...")

Так как необходимо, например, изменить первых трех пришельцев, мы выберем срез из основного списка из первых трех пришельцев. Все пришельцы имею параметр цвета "green", но это не всегда так, поэтому мы пишем условие "if", чтобы убедиться, что мы модифицируем только зеленых пришельцев. Если инопланетянин зеленого цвета, мы меняем параметр цвета на "yellow", скорость на "medium", а значение баллов 10, как показано в следующем выводе:

{'speed': 'medium', 'color': 'yellow', 'points': 10}
{'speed': 'medium', 'color': 'yellow', 'points': 10}
{'speed': 'medium', 'color': 'yellow', 'points': 10}
{'speed': 'slow', 'color': 'green', 'points': 5}
{'speed': 'slow', 'color': 'green', 'points': 5}
...

Можно также расширить этот цикл, добавив условие "elif", который превращает желтых инопланетян в красных, c параметром скорости "fast" и имеющих параметр баллов - 15. Без повторения всей программы этот цикл будет выглядеть так:

for alien in aliens[0:3]:
    if alien['color'] == 'green':
        alien['color'] = 'yellow'
        alien['speed'] = 'medium'
        alien['points'] = 10
    elif alien['color'] == 'yellow':
        alien['color'] = 'red'
        alien['speed'] = 'fast'
        alien['points'] = 15

Обычно это удобно хранить несколько словарей в списке, когда каждый словарь содержит много типов данных об одном объекте. Например, можно создать словарь для каждого пользователя на веб-сайте, как мы это делали ранее, и сохранить отдельные словари в списке, называемом пользователи. Все словари в списке должны иметь одинаковую структуру, чтобы вы могли перебирать список и работать с каждым объектом словаря одинаково.

Списки в словаре

Вместо помещения словаря в список, иногда можно создать список в словаре. Например, подумайте, как бы вы описали пиццу, которую кто-то заказывает. Если бы вы использовали только список, все, что вы действительно могли бы сохранить, это только список её добавок. С помощью словаря список добавок может быть лишь одним из аспектов пиццы, которую вы описываете.

В следующем примере для каждой пиццы хранятся два вида информации: тип пиццы и список начинок. Список добавок - это значение, связанное с ключом «toppings». Чтобы использовать элементы в списке, мы даем имя словаря и ключ 'toppings', как и любое значение в словаре. Вместо того, чтобы возвращать одно значение, мы получаем список начинки:

# Store information about a pizza being ordered.
pizza = {
    'crust': 'thick',
    'toppings': ['mushrooms', 'extra cheese'],
    }

# Summarize the order.
print("You ordered a " + pizza['crust'] + "-crust pizza " + "with the following toppings:")

for topping in pizza['toppings']:
    print("\t" + topping)

Мы начнем со словаря, который содержит информацию о заказанной пицце. Одним из ключей в словаре является тип пиццы "crust", а связанным значением является строка «thick». Следующий ключ, «toppings», имеет в качестве значения список, в котором хранятся все запрошенные добавки. Затем выводим итог заказа, прежде чем приготовить пиццу. Чтобы вывести добавки пиццы, нужно использовать цикл "for". Чтобы получить доступ к списку добавок, далее используем ключ "toppings", и Python извлекает список значений словаря. Получаем следующий результат:

You ordered a thick-crust pizza with following toppings:
    mushrooms
    extra chesse

Таким образом можно вложить список в словарь в любое время, когда хотите, чтобы с одним ключом в словаре было связано более одного значения. В предыдущем примере с любимыми языками программирования, если бы мы сохраняли ответы каждого пользователя в списке, была бы возможность выбрать более одного любимого языка. Когда мы перебираем словарь, значение, связанное с каждым человеком, будет выводится списком языков, а не одним значением. Внутри цикла for в словаре мы используем другой цикл "for" для просмотра списка языков, связанных с каждым человеком:

favorite_languages = {
    'jen': ['python', 'ruby'],
    'sarah': ['c'],
    'edward': ['ruby', 'go'],
    'phil': ['python', 'haskell'],
    }

for name, languages in favorite_languages.items():
    print("\n" + name.title() + "'s favorite languages are:")
    for language in languages:
        print("\t" + language.title())

Чтобы еще больше усовершенствовать эту программу, вы можете включить оператор if в начале цикла словаря for, чтобы узнать, имеет ли каждый человек более одного любимого языка, используя функцию len(languages). Если у человека есть более одного фаворита, результат останется прежним. Если у человека есть только один любимый язык, вы можете изменить формулировку, чтобы отразить это. Например, вы могли бы сказать, что любимый язык Сары - C.

Примечание: Не следует слишком глубоко вкладывать списки в словари. Если вы вкладываете элементы глубже, чем вы видели в предыдущих примерах, или вы работаете с чужим кодом со значительным уровнем вложенности, скорее всего, существует более простой способ решения проблемы.

Словарь в словаре

Можно также вложить словарь в другой словарь, но тогда код может быстро усложниться. Например, если у вас есть несколько пользователей для веб-сайта, каждый с уникальным именем пользователя, вы можете использовать имена пользователей в качестве ключей в словаре. Затем можно сохранить информацию о каждом пользователе, используя словарь в качестве значения, связанного с именем пользователя. В следующем списке мы сохраним три части информации о каждом пользователе: его имя, фамилия и местоположение. Мы получим доступ к этой информации, просматривая имена пользователей и словарь информации, связанной с каждым именем пользователя:

users = {
    'einstrin': {
        'first': 'albert',
        'last': 'einstein',
        'location': 'princeton',
    },
    'mcurie': {
        'first': 'marie',
        'last': 'curie',
        'location': 'paris',
    },
}

for username, user_info in users.items():
    print("\nUsername: " + username)
    full_name = user_info['first'] + " " + user_info['last']
    location = user_info['location']

    print("\tFull name: " + full_name.title())
    print("\tLocation: " + location.title())

Сначала зададим переменную для словаря под названием "users" с двумя ключами: по одному для имен пользователей "einstein" и "mcurie". Значение, связанное с каждым ключом, представляет собой словарь, который включает имя, фамилию и местоположение каждого пользователя. Затем мы перебираем пользовательский словарь. Python сохраняет каждый ключ в переменной "username", а словарь, связанный с каждым именем пользователя, переходит в переменную "user_info". Оказавшись внутри основного цикла, мы выводим имя пользователя.

После этого мы начинаем доступ к внутреннему словарю. Переменная "user_info", которая содержит словарь информации пользователей, имеет три ключа: "first", "last" и "location". Мы используем каждый ключ, чтобы сгенерировать аккуратно отформатированное полное имя и местоположение для каждого пользователя, а затем выводим сводку того, что мы знаем о каждом пользователе:

Username: aeinstein
    Full name: Albert Einstein
    Location: Princeton
Username: mcurie
    Full name: Marie Curie
    Location: Paris

Обратите внимание, что структура каждого пользовательского словаря идентична. Хотя это не требуется, но такая структура облегчает работу с вложенными словарями. Если бы у каждого пользовательского словаря были разные ключи, код внутри цикла "for" был бы более сложным.

Примечание

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

В последующих статьях узнаем о том, как принимать входные данные от людей, которые используют ваши программы. Вы научитесь делать все свои программы интерактивными: они смогут реагировать на ввод пользователя. Если остались вопросы, комментарии, то Вы всегда можете их оставить на странице обсуждения данной статьи.

Другие статьи о Python