return the first element with a difference from two lists of lists and stop to compare

358 views Asked by At

I work on a project on python and I need to return the first delta (difference) beetween two lists of lists. And each position in the inside list refer to a name.

I succed to return the first delta for each parameter but I would like to stop at the first sublist with a delta.

My actual code is :

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()

I use break to stop to compare the sublist but it continu to compare the next sublist.

Output :

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

But I would like only:

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

because it's the first index with a delta

if I add return l_par[i] it will print the ALPHA one but as we seen it's in index 3 so not in the first sublist with the delta.

3

There are 3 answers

0
Kirill On

Usually it is done with a flag around inner loop but in Python you could use for ... else:

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

The trick is the code inside else statement executes when the inner for loop terminates but not when it is terminated by break statement.

0
AudioBubble On

You could do it like this:

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()

[Note: You'll need Python 3.8+]

0
Alex On

Note : sorry for the mistake l_par is l_name. I forgot to change the name.

Ok the answer was simple sorry,

It only need to reverse the for loop and use 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()