Пытаясь понять поиск через вложенный диктат - PullRequest
0 голосов
/ 14 мая 2018

У меня есть список контактной информации, хранящейся во вложенном dict:

addressBook = {'Jim': {'name': 'James Marsh', 'address': '32 Morris Ave',
                           'phone': '654-987-3217'},
    'Leanne': {'name': 'Leanne Moss', 'address': '37 Shamrock Lane',
                           'phone': '123-456-7890'},
    'Chris': {'name': 'Christopher Philips', 'address': '49 Langley Court',
                           'phone': '321-654-9870'},
'Tim': {'name': 'Timothy Morris', 'address': '49 Langley Court',
                       'phone': '321-654-9870'}}

, и я пытаюсь написать функцию, которая будет искать в каждой записи введенную пользователем строку поиска.

def searchAllFields(addressBook):
    searchString = input("Enter a string to search for (enter to cancel): ")
    if searchString == "":
        return
    else:
        for key, value in addressBook.items():
            inside = False
            for v in value.values():
                if searchString in v:
                    inside = True
                    break
            if searchString in key or inside:
                print("The following contacts were found: ")
                print(addressBook[key]['name'])
                print(addressBook[key]['address'])
                print(addressBook[key]['phone'] + '\n')
            else:
                print("No contact matching the string {} was found.".format(searchString))
                return

Моя функция хорошо просматривает словарь, но находит только строку поиска в ключах.Например, если моя строка поиска в Jim, я могу найти информацию Джеймса, но если моя строка поиска Lang, я хочу найти Криса.Я бы подумал, что for key, value in addressBook.items(): будет просматривать значения, а также ключи.Почему не так?Как я мог это исправить?

Ответы [ 2 ]

0 голосов
/ 14 мая 2018

Вам необходимо проверить, является ли ввод подстрокой значений или keys или значений в вашем вложенном словаре.

Если частичные совпадения приемлемы, вы можете достичь этого, используя any с выражением генератора:

for key, value in addressBook.items():
    if (searchString in key) or any(searchString in i for i in value.values()):
        print(...)

Разновидностью этого является использование collections.namedtuple, что имеет больше смысла для структурированных данных. Это включает одноразовые затраты на трансформацию.

from collections import namedtuple

Contact = namedtuple('Contact', ['name', 'address', 'phone'])
d = {k: Contact(**v) for k, v in addressBook.items()}

for key, value in d.items():
    if (searchString in key) or any(searchString in i for i in value):
        print(...)
0 голосов
/ 14 мая 2018

Когда вы делаете searchString in value, вы проверяете только ключи этого value словаря.

Вам понадобится второй цикл для проверки значений во вложенном словаре

for key, value in addressBook.items():
    inside = False
    for v in value.values():
        if searchString in v:
            inside = True 
            break
    if searchString in key or inside:

Несвязанное примечание: searchString in key проверяет подстроки, а не точное соответствие

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...