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 vals1
and vals2
and return a message or a list depending on the result of the comparison. If vals1
and 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 (vals1
and 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
[('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.
CodePudding user response:
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)
CodePudding user response:
I'd suggest using enumerate()
as opposed to using range()
. You can also remove the else
in the function, as it's redundant:
def compareLists(l1, l2, names):
if l1 == l2:
return "Equal"
return ([(item, idx, val) for idx, (item, val) in
enumerate(zip(names, l1)) if l1[idx] != l2[idx]])
vals1=[12, 2, 2, 7, 5]
vals2=[12, 5, 2, 7, 15]
names=['a','b','c','d','e']
print(compareLists(vals1, vals2, names))