2013-06-20 3 views
2

Так вот мой вопрос:Python поиска ключей словаря для поиска ввода

Я хочу, чтобы искать словарь, чтобы увидеть, если какой-либо ключ содержит пользовательские введенные ключевые слова. Например, пользователь ищет Джона.

elif option == 3: 
     count = 0 
     found = None 
     search_key = input("What do you want to search for? ").lower() 
     for key, val in telephone_directory.items(): #takes each element in telephone directory 
      if search_key in key: #checks if it contains search_key 
       if found is None: 
        found = val 
        count = 1 
       if found is not None: 
        print(" ") 
        print("More than one match found. Please be more specific.") 
        print(" ") 
        count = 2 
        break 

      if found is None: 
       print("Sorry, " + str(search_key) + " was not found.") 
       print(" ") 
       function_options() #redirects back 

      if found is not None and count < 2: 
       print(str(search_key) + " was found in the directory.") 
       print("Here is the file on " + str(search_key) + ":") 
       print(str(search_key) + ":" + " " + telephone_directory[search_key]) 
       print(" ") 
       function_options() #redirects back 

Так вот, где я сейчас. Какой бы поиск ни был, даже если это весь ключ, он возвращает «не найден». Что я делаю не так?

+0

Я хочу, чтобы сделать некоторые соответствия на части имени, вы должны ожидать случая, когда возможны несколько возвратов. Что должно произойти в таком случае? – Josay

+0

Я добавлю случай, где, если он отображает больше 2, он попросит пользователя более конкретно. Не большая проблема. – Aristides

ответ

2

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

Чтобы найти первый матч, используйте next():

match = next(val for key, val in telephone_directory.items() if search_key in key) 

Это поднимет StopIteration, если совпадение найдено не было; возвращает значение по умолчанию вместо или поймать исключение:

# Default to `None` 
match = next((val for key, val in my_dict.items() if search_key in key), None) 

try: 
    match = next(val for key, val in telephone_directory.items() if search_key in key) 
except StopIteration: 
    print("Not found") 

Этих версии будут только перебирает словарные элементы, пока не будет найдено совпадение, то остановить; полный цикл for эквивалентная бы:

for key, val in telephone_directory.items(): 
    if search_key in key: 
     print("Found a match! {}".format(val)) 
     break 
else: 
    print("Nothing found") 

else Обратите внимание на блок; он вызывается только тогда, когда цикл for был разрешен для завершения и не был прерван оператором break.

Чтобы найти всех ключей соответствия, использование может использовать список понимание:

matches = [val for key, val in telephone_directory.items() if search_key in key] 

Наконец, чтобы только один матч, эффективно использовать два next() вызовов на тот же итератор, и вызвать ошибку если второе совпадение найдено:

def find_one_match(d, search_key): 
    d = iter(d.items()) 
    try: 
     match = next(val for key, val in d if search_key in key) 
    except StopIteration: 
     raise ValueError('Not found')  

    if next((val for key, val in d if search_key in key), None) is not None: 
     raise ValueError('More than one match') 

    return match 

Адаптация, что подход к for петли снова, потребуется вам, чтобы разорвать, только если второй элемент найден:

found = None 
for key, val in telephone_directory.items(): 
    if search_key in key: 
     if found is None: 
      found = val 
     else: 
      print("Found more than one match, please be more specific") 
      break 
else: 
    if found is None: 
     print("Nothing found, please search again") 
    else: 
     print("Match found! {}".format(found)) 

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

+0

Используйте только один матч. Если несколько совпадений, попросите пользователя ввести больше ввода (более конкретный поиск). Спасибо хоть! И можете ли вы записать их в блоках? Счастье, новичок! – Aristides

+0

, но почему он не работает так, как я изначально его положил? Не так ли? – Aristides

+0

, но зачем нужен цикл for? Я просто ищу ключи ... – Aristides

Смежные вопросы