Если у вас есть три или более пронумерованных и аналогично используемых переменных, подумайте о списках.
Учитывая это, мы сначала меняем 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)
Когда вам нужно вырваться из нескольких циклов сразу, подумайте о функциях и вернитесь, вместо того чтобы ломаться. Или исключения и блоки try, но некоторые могут обнаружить, что это неприятно.
Неисправный флаг работает, но не очень изящный. Есть преувеличенное высказывание: "... if you need more than 3 levels of indentation, you're screwed anyway, and should fix your program." Прочитайте это как: Если у вас много уровней отступов (и некоторые языки требуют больше, чем другие), вы должны подумать о том, можете ли вы переместить часть логики в функцию.
Мы также переместим некоторую повторяющуюся логику в функцию проверки.
(Наконец, я думаю, что это ошибка, что ваша вторая для цикла вложен в ваш первый. Так как они имеют один и тот же итератор переменную 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)
Перепишите их как 'if X == Y и Z == W и ...' в том же порядке? – favoretti
Этот _really_ ваш код, или просто что-то сделанное, чтобы показать много вложенного кода? Каким должен быть код? Это поиск данных? Выполняет ли это вычисление? В зависимости от ответа на эти вопросы реальным ответом может быть изменение структуры данных, чтобы избежать необходимости всех условных проверок. –
Может быть, совершенно другой и лучший способ сделать то, что вы пытаетесь сделать ... Не могли бы вы добавить описание предполагаемой функции (входы/выходы)? – jpwagner