2013-06-20 95 views
2

因此,这里是我的问题:用于搜索输入的Python搜索字典键

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

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

+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

只允许一场比赛。如果有多个匹配,请向用户提供更多输入(更具体的搜索)。虽然谢谢!你能写出它们吗? Srry,初学者! – Aristides

+0

但为什么它不按照我最初的方式工作?不应该吗? – Aristides

+0

但为什么for循环还需要val?我只是在搜索键... – Aristides