верните первый элемент с отличием от двух списков списков и остановитесь для сравнения

#python #list #compare #sublist #delta-index

Вопрос:

Я работаю над проектом на python, и мне нужно вернуть первую дельту (разницу) между двумя списками списков. И каждая позиция во внутреннем списке ссылается на имя.

Мне удалось вернуть первую дельту для каждого параметра, но я хотел бы остановиться на первом подсписке с дельтой.

Мой фактический код таков :

 l_name = ["TIME", "ALPHA", "BETA"]         # the list of names
liste1 = [[1, 2, 3.0], [2,5.045,6.003], [3, 8.03, 9], [4, 10.5, 5.5]]     # values of all name in one sublist by step time
liste2 = [[1, 2, 3.0], [2,5.045,6.005], [3, 8.0029, 9], [4, 10.5, 5.5555]]
abs_tol = 0.00001                # tolerence to found a delta

def search_var_delta():
    for i in range(len(l_name)):
        for k in range(len(liste1)):
            a = liste1[k][i]
            b = liste2[k][i]
            diff = abs(a-b)
            if diff >= abs_tol :
                print("the delta : {}".format(diff),
                      "the index : {}".format(k 1),
                      "the parameter : {}".format(l_par[i]))
                break

search_var_delta()
 

Я использую break, чтобы остановить сравнение подсписка, но оно продолжается для сравнения следующего подсписка.

Выход :

 ('the delta : 0.0271', 'the index : 3', 'the parameter : ALPHA')
('the delta : 0.002', 'the index : 2', 'the parameter : BETA')
 

Но я хотел бы только:

 ('the delta : 0.002', 'the index : 2', 'the parameter : BETA')
 

потому что это первый индекс с дельтой

если я добавлю return l_par[i] , он напечатает АЛЬФА-единицу, но, как мы видели, она находится в индексе 3, а не в первом подсписке с дельтой.

Комментарии:

1. l_par не определено.

2. Вы только выходите из внутреннего цикла, внешний будет продолжать работать. Вы можете изменить цикл for на цикл while и добавить условие или создать логическую переменную, которую вы установили во внутреннем цикле перед разрывом, и использовать ее для разрыва внешнего цикла.

Ответ №1:

Обычно это делается с флагом вокруг внутреннего цикла, но в Python вы могли бы использовать для … ещё:

 def search_var_delta():
    for i in range(len(l_name)):
        for k in range(len(liste1)):
            # ...
            if diff >= abs_tol :
                # ...
                break
        else:
            continue
        break
 

Хитрость в том, что внутренний else оператор кода выполняется, когда внутренний for цикл завершается, но не тогда, когда он завершается break оператором.

Ответ №2:

Ты мог бы сделать это вот так:

 l_name = ["TIME", "ALPHA", "BETA"]
liste1 = [[1, 2, 3.0], [2,5.045,6.003], [3, 8.03, 9], [4, 10.5, 5.5]]
liste2 = [[1, 2, 3.0], [2,5.045,6.005], [3, 8.0029, 9], [4, 10.5, 5.5555]]
tolerance = 0.00001
def process():
    for i, v in enumerate(zip(liste1, liste2), 1):
        for j in range(len(v[0])):
            if (delta := abs(v[0][j]-v[1][j])) > tolerance:
                print(f'Delta = {delta:.3f}, index = {i}, parameter = {l_name[j]}')
                return
process()
 

[Примечание: Вам понадобится Python 3.8 ]

Ответ №3:

Примечание : извините за ошибку, l_par-это l_name. Я забыл сменить имя.

Хорошо, ответ был прост, извините,

Для этого нужно только отменить цикл for и использовать return :

 def search_var_delta():
    for k in range(len(liste1)):
        for i in range(len(l_name)):
            a = liste1[k][i]
            b = liste2[k][i]
            diff = abs(a-b)
            if diff >= abs_tol :
                print("the delta : {}".format(diff),
                      "the index : {}".format(liste1[k][0]),
                      "the parameter : {}".format(l_name[i]))
                return [diff, liste1[k][0], l_name[i]]

search_var_delta()