用于搜索输入的Python搜索字典键

时间:2013-06-20 13:15:52

标签: python dictionary python-3.x

所以这是我的问题:

我想搜索字典以查看是否有任何键包含用户输入的关键字。例如,用户搜索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  

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

1 个答案:

答案 0 :(得分: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))

您的版本不起作用,因为您为打印了“未找到”每个不匹配的密钥。只有当你迭代了字典中的所有键时,才能知道你没有匹配一个键。