Python—有什么方法可以避免for循环中彼此内部的几个if语句?

2024-09-27 07:30:02 发布

您现在位置:Python中文网/ 问答频道 /正文

我需要一个更好的方法。我是新来的编程人员,但我知道这是一种非常低效的方法,我需要一个函数来实现这一点,我只是不知道如何做到这一点。有什么建议吗?我非常感谢你的帮助!

for H in range(0,len(a_list)):
    if a_list[H] > list4[0]:
        list5 = [number_list[i]]
        if function(list1,list5) == list1[1]:
            if function(list2,list5)== list2[1]:
                if function(list3,list5)== list3[1]:
                    if function(list4,list5)== list4[1]:
                        list5.append(input('some input from the user'))
                        other_function(list5)
                        if list5[1]== 40:
                            print ('something something')
                            break out of EVERY loop 
                         else: 
                            for H in range(0,len(a_list)):
                                if a_list[H] > list5[0]:
                                    list6 = [number_list[i]]
                                    if function(list1,list6) == list1[1]:
                                        if function(list2,list6)== list2[1]:
                                            if function(list3,list6)== list3[1]:
                                               if function(list4,list6)== list4[1]:
                                                  if function(list5,list6)== list5[1]:
                                                     list6.append(input('some input from theuser'))
                                                     other_function(list6)
                                                         if list6[1]== 40:
                                                             print ('something something')
                                                                 break out of EVERY loop 
                                                         else: 
                                                            etc. (one extra comparison every time)  

Tags: 方法inforinputifrangefunctionsomething
2条回答

当你有三个或更多的数字和类似的使用变量,思考列表。

考虑到这一点,我们首先更改list1,list2,list3。。。进入列表列表(索引为0,1,2,3而不是1,2,3,4)。但不要叫它list,因为这是一个对已经有用的东西有用的名字。lst在Python中非常流行。我还要把list5改成lstA,list6改成lstB,因为5和6不再有意义了。

现在我们有了这个:

for H in range(0,len(a_list)):
    if a_list[H] > lst[3][0]:
        lstA = [number_list[i]]
        if function(lst[0],lstA) == lst[0][1]:
            if function(lst[1],lstA)== lst[1][1]:
                if function(lst[2],lstA)== lst[2][1]:
                    if function(lst[3],lstA)== lst[3][1]:
                        lstA.append(input('some input from the user'))
                        other_function(lstA)
                        if lstA[1]== 40:
                            print ('something something')
                            break out of EVERY loop 
                         else: 
                            for H in range(0,len(a_list)):
                                if a_list[H] > lstA[0]:
                                    lstB = [number_list[i]]
                                    if function(lst[0],lstB) == lst[0][1]:
                                        if function(lst[1],lstB)== lst[1][1]:
                                            if function(lst[2],lstB)== lst[2][1]:
                                               if function(lst[3],lstB)== lst[3][1]:
                                                  if function(lstA,lstB)== lstA[1]:
                                                     lstB.append(input('some input from theuser'))
                                                     other_function(lstB)
                                                         if lstB[1]== 40:
                                                             print ('something something')
                                                                 break out of EVERY loop 
                                                         else: 
                                                            etc. (one extra comparison every time)  

现在更明显的是,我们基本上做了四次同样的事情。


当你不得不做同样的事情很多次,想循环。

我们将把这些块换成圈。我们还将使用一个标志变量来跟踪在测试我们的逻辑时是否失败,并使用逻辑“如果它不起作用,就跳过一些事情”而不是“如果它起作用,就做一些事情”

for H in range(0,len(a_list)):
    if a_list[H] > lst[3][0]:
        continue #reducing indent levels by negating the check:
                 #quit on failure instead of work on success

    lstA = [number_list[i]]

    quit = False

    for j in range(4):
        if function(lst[j],lstA) != lst[j][1]: #testing FALSEHOOD
            quit = True
            break #the j loop only

    if quit:
        continue #reducing indent levels by negating the check

    lstA.append(input('some input from the user'))
    other_function(lstA)
    if lstA[1]== 40:
        print ('something something')
        break #out of EVERY loop
    #else: #don't need the else because we broke

    for H in range(0,len(a_list)):
        if not a_list[H] > lstA[0]:
            continue #reducing indent levels by negating the check

        lstB = [number_list[i]]

        for j in range(4):
            if function(lst[j],lstB) != lst[j][1]: #testing FALSEHOOD
                quit = True;
                break #to the H loop
        if not quit and  function(lstA,lstB)== lstA[1]: #combining two checks
            lstB.append(input('some input from theuser'))
            other_function(lstB)
            if lstB[1]== 40:
                print ('something something')
                break #out of EVERY loop
            else: #at this point I'm lost and can't refactor
                etc. (one extra comparison every time)  

当您必须同时中断多个循环时,请考虑函数并返回而不是中断。或者是例外情况,试一下积木,但有些人可能会觉得不舒服。

失败的旗帜有效,但不是很优雅。有句夸张的话:"... if you need more than 3 levels of indentation, you're screwed anyway, and should fix your program."把它读成:如果你有很多级别的缩进(有些语言比其他语言需要更多),你应该考虑是否可以将一些逻辑移到一个函数中。

我们还将把一些重复的逻辑移到checker函数中。

(最后,我认为第二个for循环嵌套在第一个for循环中是一个bug。因为它们有相同的迭代器变量H,我想这会导致无限循环。所以我修好了。)

#returns FALSE if a check fails, unlike the `quit` variable
def checker(lst, lstA):
    for i in range(4):
        if function(lst[i],lstA) != lst[i][1]: #testing FALSEHOOD
            return False;
    return True;


def main(???):
    for H in range(0,len(a_list)):
        if a_list[H] > lst[3][0]:
            continue

        lstA = [number_list[i]]

        if not checker(lst,lstA):
            continue

        lstA.append(input('some input from the user'))
        other_function(lstA)
        if lstA[1]== 40:
            print ('something something')
            return #break out of EVERY loop

    for H in range(0,len(a_list)):
        if not a_list[H] > lstA[0]:
            continue

        lstB = [number_list[i]]

        if checker(lst,lstB) and  function(lstA,lstB) == lstA[1]:
            lstB.append(input('some input from theuser'))
            other_function(lstB)
            if lstB[1]== 40:
                print ('something something')
                return # break out of EVERY loop
            else: #at this point I'm lost and can't refactor
                etc. (one extra comparison every time)  

使用^{} function测试多个相关条件:

if all(function(lst, list5) == lst[1] for lst in (list1, list2, list3, list4)):

以及

if all(function(lst, list6) == lst[1] for lst in (list1, list2, list3, list4, list5)):

就像嵌套的if语句一样,all()将短路;一旦任何测试失败,返回False

此外,直接循环列表,而不是生成一系列索引。如果您使用的是break,那么也不需要使用else,删除另一级别的缩进。

您可以通过筛选a_list删除另一个级别:

for H in filter(lambda H: H > list4[0], a_list):

总之,这将减少您的嵌套:

for H in filter(lambda H: H > list4[0], a_list):
    list5 = [number_list[i]]
    if all(function(lst, list5) == lst[1] for lst in (list1, list2, list3, list4)):
        list5.append(input('some input from the user'))
        other_function(list5)
        if list5[1]== 40:
            print ('something something')
            break # out of EVERY loop 

        for J in filter(lambda J: J >list5[0], a_list):
            if all(function(lst, list6) == lst[1] for lst in (list1, list2, list3, list4, list5)):
            list6.append(input('some input from theuser'))
            other_function(list6)
            if list6[1]== 40:
                print ('something something')
                break # out of EVERY loop 

            # continue here

假设您的break语句实际使用异常(raise CustomException()try:except CustomException: # break out of all the loops fast),因为常规的break只会停止当前循环。

如果继续添加更多列表和嵌套,可能需要使用列表来保存所有这些嵌套列表,然后只需添加到外部列表:

class EndLoops(Exception): pass

stack = [[number_list[0]]]
try:
    for i in number_list[1:]:
        for H in filter(lambda H: H > stack[-1][0], a_list):
            stack.append([i])
            if all(function(lst, stack[-1]) == lst[1] for lst in stack[:-1]):
                stack[-1].append(input('some input from the user'))
                other_function(stack[-1])
                if stack[-1][1] == 40:
                    print ('something something')
                    raise EndLoops
except EndLoops:
    pass # broken out of outer loop

突然之间,所有的嵌套都消失了;相反,您将嵌套移到了列表列表的stack列表中。

请注意,我不知道在您的代码中最外层的循环是什么样子的,我只是在黑暗中接受了教育,但这个想法应该大致正确。

相关问题 更多 >

    热门问题