本文转载自公众号《核心阅读》(ID:AI_Discovery)问题源于生活。上周在做一个业余项目时,我遇到了一个非常有趣的设计问题:“如果用户犯了错误怎么办?”下面是如果用户犯了错误会发生什么:示例:PythonDictPython中的字典表示一个键(keys)和值(values)。例如:student_grades={'John':'A','Mary':'C','Rob':'B'}#TocheckgradeofJohn,wecallprint(student_grades['John'])#Output:A当有是现有密钥吗?print(student_grades['Maple'])#Output:KeyErrorTraceback(mostrecentcalllast)in---->print(student_grades['Maple'])KeyError:'Maple'你会收到按键错误(KeyError)提示。每当dict()为字典中不存在的键请求对象时,就会发生KeyError。这个错误在接收用户输入时很常见。例如:student_name=input("Pleaseenterstudentname:")print(student_grades[student_name])本文将为您提供几种处理Python字典keyerror的方法。打算尝试构建一个可以帮助您处理用户输入错误的python智能词典。设置默认值的一种非常方便的方法是在请求的键不存在时返回默认值。这可以通过get()方法完成:default_grade='NotAvailable'print(student_grades.get('Maple',default_grade))#Output:#NotAvailabletoresolvecaseissues假设你构建了一个包含特定人群的Python字典国家数据。该代码将要求用户输入国家名称并输出其人口。#populationinmillions。(来源:https://www.worldometers.info/world-population/population-by-country/)population_dict={'中国':1439,'印度':1380,'美国':331,'法国':65,'Germany':83,'Spain':46}#gettinguserinputCountry_Name=input('PleaseenterCountryName:')#accesspopulationusingcountrynamefromdictprint(population_dict[Country_Name])#OutputPleaseenterCountryName:France65但是,假设用户输入了'france'。目前,在我们的字典中,所有键都以大写字母开头。那么输出会是什么呢?请输入国家名称:法国------------------------------------------------------------------KeyErrorTraceback(mostrecentcalllast)in2Country_Name=input('PleaseenterCountryName:')3---->4print(population_dict[Country_Name])KeyError:'france'将收到一个错误,因为'france'不是字典中的键。图片来源:unsplash一个简单的解决方法:将所有国家/地区名称存储为小写。此外,将用户输入的所有内容转换为小写。#keys(CountryNames)arenowalllowercasepopulation_dict={'china':1439,'india':1380,'usa':331,'france':65,'germany':83,'spain':46}Country_Name=input('PleaseenterCountryName:').lower()#lowercaseinputprint(population_dict[Country_Name])PleaseenterCountryName:france65处理拼写错误但是,假设用户输入的是“Frrance”而不是“France”。我们如何解决这个问题?一种方法是使用条件语句。我们检查给定的用户输入是否可以用作键。如果不可用,输出会显示一条消息。最好将它放在循环语句中并在某些特殊标志输入(例如退出)上中断。population_dict={'china':1439,'india':1380,'usa':331,'france':65,'germany':83,'spain':46}while(True):Country_Name=input('PleaseenterCountryName(typeexittoclose):').lower()#breakfromcodeifuserentersexitifCountry_Name=='exit':breakifCountry_Nameinpopulation_dict.keys():print(population_dict[Country_Name])else:print("Pleasecheckforanytypos.DatanotAvailablefor",Country_Name)循环将继续运行直到用户输入退出。优化方法上述方法虽然“有效”,但不够“聪明”。我们希望该程序功能强大并且能够检测简单的拼写错误,例如frrance和chhina(类似于google搜索)。来源:unsplash我找到了几个适合解决关键错误的库,我最喜欢的是标准的python库:difflib。difflib可用于比较文件、字符串、列表等,生成各种形式的diff信息。该模块提供了用于比较序列的各种类和函数。我们将使用difflib的两个函数:SequenceMatcher和get_close_matches。让我们简单看一下这两个函数。1.#SequenceMatcherSequenceMatcher是difflib中的一个类,用于比较两个序列。我们定义它的对象如下:difflib.SequenceMatcher(isjunk=None,a='',b='',autojunk=True)isjunk:用于在比较两个文本块字符等时标记不需要的垃圾元素(空白,换行符).).有问题的文本因此被禁止通过。a和b:比较字符串。autojunk:一种自动将某些序列项视为垃圾的启发式方法。让我们使用SequenceMatcher来比较两个字符串chinna和china:fromdifflibimportSequenceMatcher#import#creatingaSequenceMatcherobjectcomparingtwostringscheck=SequenceMatcher(None,'chinna','china')#printingasimilarityratioonascaleof0(lowest)to1(highest)print(check.ratio())#Output#0.9090909090909091在上面的代码中,使用了ratio()方法。ratio以[0,1]范围内的浮点值形式返回序列相似性的度量。2.#get_close_matches现在提供了一种根据相似性比较两个字符串的方法。如果我们想找到与特定字符串相似的所有字符串(存储在数据库中)会怎样?get_close_matches()返回一个列表,其中包含可能性列表中的最佳匹配项。difflib.get_close_matches(word,possibilities,n=3,cutoff=0.6)word:要匹配的字符串。可能性:匹配单词的字符串列表。可选n:要返回的最大匹配数。默认为3;且必须大于0。可选截止值:相似度必须高于此值。默认值为0.6。可能的最佳n匹配项在列表中返回,按相似性分数排序,最相似的排在最前面。来源:unsplash看下面例子:fromdifflibimportget_close_matchesprint(get_close_matches("chinna",['china','france','india','usa']))#Output#['china']Summary现在difflib可以used,所以让我们结合所有内容来构建一个防错的python字典。当用户提供的国家名称不在population_dic.keys()中时,需要格外小心。我们应该尝试找到一个名称与用户输入相似的国家并输出其人口。#passcountry_nameinwordanddictkeysinpossibilitiesmaybe_country=get_close_matches(Country_Name,population_dict.keys())#Thenwepickthefirst(mostsimilar)stringfromthereturnedlistprint(population_dict[maybe_country[0]])最后的代码还需要考虑其他一些情况。例如,如果没有类似的字符串,或者如果用户没有确认这是想要的字符串。如下:fromdifflibimportget_close_matchespopulation_dict={'china':1439,'india':1380,'usa':331,'france':65,'germany':83,'spain':46}while(True):Country_Name=input('PleaseenterCountryName(typeexittoclose):').lower()#breakfromcodeifuserentersexitifCountry_Name=='exit':breakifCountry_Nameinpopulation_dict.keys():print(population_dict[Country_Name])else:#lookforsimilarstringsmaybe_country=get_close_matches(Country_Nameinpopulation_dictbe,countmay)=[]:#nosimilarstringprint("Pleasecheckforanytypos.DatanotAvailablefor",Country_Name)else:#userconfirmationans=input("Doyoumean%s?Typeyorn."%maybe_country[0])ifans=='y':#ify,returnpopulationprint(population_dict[maybe_country[0]])else:#ifn,startagainprint("Badinput.Tryagain.")输出:Inida实际上是印度。这样,用户的大小写混淆或输入错误处理都不是问题。您还可以进一步研究各种其他应用程序,例如使用NLP更好地理解用户输入并在搜索引擎中显示类似结果。你学会了如何构建Python智能词典吗?