3

所以这是我的问题:

我想搜索字典以查看是否有任何键包含用户输入的关键字。例如,用户搜索 John。

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  

所以这就是我现在的位置。无论搜索是什么,即使它是整个键,它也会返回“未找到”。我究竟做错了什么?

4

1 回答 1

3

你需要做出一些选择;允许多个匹配,仅查找第一个匹配,或最多只允许一个匹配。

要查找第一个匹配项,请使用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))

您的版本不起作用,因为您为每个不匹配的键打印“未找到”。您只能在遍历字典中的所有键时才知道您没有匹配键。

于 2013-06-20T13:25:29.233 回答