背景信息:
嘿,我想做以下的事情:我有一个字典,其中ID作为键,列表中有各种各样的东西作为值。值的其中一项是字符串。我要检查列表是否包含此字符串。我想把字典里的所有键都记下来。
如果列表包含字符串,我要打印"字符串有效"
如果列表不包含字符串,我要打印"字符串无效"
到目前为止,一切都很好。
此外,我想要检查的列表依赖于用户的一个控制台输入,它指定了应该检查哪个列表。控制台输入为"数字"。
我的想法是用嵌套的for循环迭代我的字典和列表,并比较,如果字符串(值的项)等于任何列表项。如果是的话,我想打破这个循环。如果在列表中找不到该字符串,我希望执行else语句以打印"string is not valid"消息。代码片段:
def validationHelper(myDict, myList):
for key in myDict:
for value in myDict[key][0]:
for item in myList:
if value==item:
validationHelper.true="String is valid"
break
else:
validationHelper.true="Warning: String is NOT valid"
def validation(anyList,helperfunc):
if anyList=="one":
return helperfunc(finalDict,myList1)
if anyList=="two":
return helperfunc(finalDict,myList2)
if anyList=="three":
return helperfunc(finalDict,myList3)
validation(number, validationHelper)
print(validationHelper.true)
问题:
我正在运行这个,但是无论字符串是否在列表中,我总是得到else语句的打印输出。那么,我想我在for循环中的推理有错误吗?或者,我根本不理解循环?!我用else语句尝试了不同的缩进,但无法解决我的问题。
记住,这里有三个嵌套的循环;break只会从最里面的循环中断。
哦,伙计,@danielroseman,我自己就知道了。现在,让我把我的"思考"用词来表达:我在列表中找到字符串,并打破内部循环。我回到循环中,"在我的dict[key][0]中寻找值",然后搜索下一个键等。我的打印将是最后一件事,它将被写入validationhelper.true,对吗?为了在找到匹配项时完全终止所有循环,我将添加break语句,对吗?
其他答案对如何突破多个循环给出了很好的解释。但是,您也可以通过使用Python的内置函数和列表理解来简化代码,如下所示:
def validationHelper(myDict, myList):
if any(v in myList for val in myDict.values() for v in val[0]):
validationHelper.true="String is valid"
else:
validationHelper.true="Warning: String is NOT valid"
def validation(anyList,helperfunc):
if anyList=="one":
return helperfunc(finalDict,myList1)
if anyList=="two":
return helperfunc(finalDict,myList2)
if anyList=="three":
return helperfunc(finalDict,myList3)
validation(number, validationHelper)
print(validationHelper.true)
这应该和您的代码一样有效,因为any在第一次匹配时会短路。它的可读性可能会提高一点。(请注意,多级列表理解与常规for循环的顺序相同。)
使用"返回"中断所有循环。如果没有任何if语句作为开头,则不需要使用else语句。
def validationHelper(myDict, myList):
for item in myList:
if item in myDict.values():
return ("String is valid")
return ("String is NOT valid")
def validation(anyList,helperfunc):
if anyList=="one":
return helperfunc(finalDict,myList1)
elif anyList=="two":
return helperfunc(finalDict,myList2)
elif anyList=="three":
return helperfunc(finalDict,myList3)
validation(number, validationHelper)
print(validationHelper.true)
使用elif而不是多个if是一个更好的实践。下次小心缩进。
另外,您可能还需要检查.keys()和.values()。
您可以替换:
for key in myDict:
for value in myDict[key][0]:
用:
for value in myDict.values():
然而,我的"else"原本是一个for loop else子句,而不是if/else:book.pythontips.com/en/latest/for_uuuuelse.html的else子句。
那你就不需要别的说法了。让我更新我的答案
我建议您按照以下方式(不改变逻辑)改变您的功能:
def validationHelper(myDict, myList):
for key in myDict:
for value in myDict[key][0]:
for item in myList:
if value==item:
return"String is valid" # Add here to exit
return"Warning: String is NOT valid" # will be returned inf nothing will be found in your 3 loops
def validation(anyList,helperfunc):
if anyList=="one":
return helperfunc(finalDict,myList1)
if anyList=="two":
return helperfunc(finalDict,myList2)
if anyList=="three":
return helperfunc(finalDict,myList3)
validation(number, validationHelper)
print(validationHelper)
这将帮助您退出注释中提到的3个嵌套循环。因为在第一次错误发生的负面情况下,您不需要检查任何其他内容。
返回值不应该代替中断值,而不是在其他情况下?
那么,返回的意思是"结束所有循环",基本上是这样工作的?因为,如果我以这种方式调整代码并尝试打印(validationhelper.true),我会得到以下错误:print(validationhelper.true)attributeError:'function'对象没有属性'true'
@Lukesmith当然,抱歉,更新了
@如果字典中第一个键出现负的情况,我想继续使用第二个键。所以我需要继续检查,只是我有了一个新的字符串,来对照同一个列表进行检查。
@Shushiro很抱歉误读了你的问题,请查看我最新的答案。返回意味着"停止执行这个函数"并返回一些东西。哦,你需要返回字符串而不是.true。
@阿森尼啊,好吧,不知怎么的,最新的答案刚刚出现
是否需要最里面的循环?我认为in关键字可以使它更易读、更惯用。
@是的,但我的答案并不是要审查代码(我们有专门的网站)。我只想指出问题的基本问题。
这不会打印验证消息。它要么需要打印validation(number, validationHelper)(可能是更好的选择),要么在返回之前将消息存储在validationHelper.true中。