Follow

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use
Contact

Pythonic way for returning elements of one list by an order-preserved comparation of two other lists

I have three lists: vals1, vals2, and names. names includes only strings and the other two lists (vals1, vals2) contain numbers only. The lengths of the three lists are always the same. My goal is to write a function that compares vals1and vals2 and return a message or a list depending on the result of the comparison. If vals1and vals2 are equal, then the function returns a message that states the two lists are equal. List comparison must be done in the preserved order. For example, vals1 = [1,2,3,2] is not equal to vals2 = [1,2,2,3]. If the two numeric lists (vals1and vals2) are not equal, the function will return a list that contains tuples. Each tuple in this list contains the index of one element in vals1 and vals2 that are not equal, the corresponding element in the string list names, and the corresponding element in vals1. This is the function that I wrote for this task:

def compareLists(l1, l2, names):
    if l1==l2:
        return "Equal"
    else:
        return ([(item, idx, val) for (item, idx, val) in 
               zip(names, range(len(names)), l1) if l1[idx]!=l2[idx]])

For

vals1=[12, 2, 2, 7, 5]
vals2=[12, 5, 2, 7, 15]
names=['a','b','c','d','e']

compareLists will return

MEDevel.com: Open-source for Healthcare and Education

Collecting and validating open-source software for healthcare, education, enterprise, development, medical imaging, medical records, and digital pathology.

Visit Medevel

[('b', 1, 2), ('e', 4, 5)]

The function works, but I wanted to know if there is a more efficient way (a more pythonic approach) to this. Any help would be appreciated.

>Solution :

There’s nothing wrong with your method, imo.

Alternatively, you could use zip + enumerate:

out = [(n, idx, i) for idx, (i, j, n) in enumerate(zip(vals1, vals2, names)) if i!=j]
out = out if out else 'equal'

If you have Python >=3.8, you can also write the above in one line (a lot less readable though):

out = out if (out:= [(n, idx, i) for idx, (i, j, n) in enumerate(zip(vals1, vals2, names)) if i!=j]) else 'equal'

Output:

[('b', 1, 2), ('e', 4, 5)]

We could also write a genexp (thanks @JonClements):

t = ((n, idx, i) for idx, (i, j, n) in enumerate(zip(vals1, vals2, names)) if i!=j)
out = 'equal' if vals1 == vals2 else list(t)
Add a comment

Leave a Reply

Keep Up to Date with the Most Important News

By pressing the Subscribe button, you confirm that you have read and are agreeing to our Privacy Policy and Terms of Use

Discover more from Dev solutions

Subscribe now to keep reading and get access to the full archive.

Continue reading