Как работать со вложенными словарями
Господа, добрый вечер! У меня есть два блока исходных данных:
documents = [
{'type': 'bird', 'number': '22', 'name': 'Кики'},
{'type': 'dog', 'number': '1', 'name': 'Шарик'},
{'type': 'cat', 'number': '13', 'name': 'Маруся'}
]
directories = {'1': ['22', '1'], '2': ['13'], '3': []}
Задача 1.
После ввода команды “p” пользователь должен получить имя животного по его номеру.
Задача 2.
После ввода команды “s” пользователь по номеру документа должен узнать, в какой директории он хранится
Задача 3.
После ввода команды “l” пользователь должен увидеть полную информацию по всем документам: комер, тип, имя и в какой директории хранится.
Я затормозила уже на первой задаче.
Использовала цикл for и пыталась вывести значения по ключам. Но максимум, что получила - имя первого животного в ответ на любой введённый номер.
Помогите, чем можете :) Можно (и нужно) вводить функции. Только не делайте пожалуйста длиннющие однострочные циклы - мне важно понять принцип алгоритма.
Ибо в теории я всё понимаю, а как дело касается практики - дико торможу.
Спасибо заранее!
Ответы (1 шт):
documents = [
{'type': 'bird', 'number': '22', 'name': 'Кики'},
{'type': 'dog', 'number': '1', 'name': 'Шарик'},
{'type': 'cat', 'number': '13', 'name': 'Маруся'}
]
directories = {'1': ['22', '1'], '2': ['13'], '3': []}
Для первой задачи нам надо просто найти словарь, где ключ number равен введённому числу. Т.е. мы можем просто в цикле проходиться по каждому елементу в documents пока не найдём то, что нам нужно, либо использовать filter с условием.
p = input('command: ')
if p == 'p':
num = input('number of animal: ')
animal = list(filter(lambda e: e['number'] == num, documents))[0]
print(animal['name']) # вывели имя животного
Для второй задачи действуем по тому же принципу. Но т.к. directories это словарь, а не список, мы должны проходиться по его ключах либо значениях этих ключей. Проще всего использовать метод directories.items(), который возвращает кортеж (ключ, значение). И собственно потом уже проверять, есть ли во втором елементе этого кортежа значение введённое с клавиатуры (номер).
if p == 'c':
num = input('number: ')
dir = list(filter(lambda e: num in e[1], directories.items()))[0]
print(dir[0]) # первый елемент, т.е. номер директории
С последним заданием всё еще проще. Если нам нужна информация по каждому животному отдельно, то просто в цикле проходимся по каждому елементу documents и ищем номер директории в которой это животное. Номер директории ищем как во втором примере, для каждого елемента (ключ, значение) словаря directories проверяем есть ли там номер нашего животного.
if p == 'l':
for animal in documents:
dir = list(filter(lambda e: animal['number'] in e[1], directories.items()))[0]
animal['directory'] = dir[0]
print(animal)
# command: l
# {'type': 'bird', 'number': '22', 'name': 'Кики', 'directory': '1'}
# {'type': 'dog', 'number': '1', 'name': 'Шарик', 'directory': '1'}
# {'type': 'cat', 'number': '13', 'name': 'Маруся', 'directory': '2'}
В итоге можно переписать все красиво:
documents = [
{'type': 'bird', 'number': '22', 'name': 'Кики'},
{'type': 'dog', 'number': '1', 'name': 'Шарик'},
{'type': 'cat', 'number': '13', 'name': 'Маруся'}
]
directories = {'1': ['22', '1'], '2': ['13'], '3': []}
def get_animal(number):
return list(filter(lambda e: e['number'] == number, documents))[0]
def get_directory(number):
return list(filter(lambda e: number in e[1], directories.items()))[0]
p = input('Команда: ')
if p == 'p':
print(get_animal(input('Номер документа: ')))
if p == 'c':
print(get_directory(input('Номер документа: '))[0])
if p == 'l':
for animal in documents:
print(animal, f"dir = {get_directory(animal['number'])[0]}")