通过两个其他列表的保留顺序比较返回一个列表元素的 Pythonic 方法
Pythonic way for returning elements of one list by an order-preserved comparation of two other lists
我有三个列表:vals1
、vals2
和 names
。 names
仅包含字符串,而其他两个列表(vals1
、vals2
)仅包含数字。三个列表的长度总是相同的。我的目标是编写一个函数,根据比较结果比较 vals1
和 vals2
和 return 消息或列表。如果 vals1
和 vals2
相等,则函数 return 是一条消息,表明两个列表相等。列表比较必须以保留的顺序进行。例如,vals1 = [1,2,3,2]
不等于 vals2 = [1,2,2,3]
。如果两个数字列表(vals1
和 vals2
)不相等,函数将 return 一个包含元组的列表。此列表中的每个元组包含 vals1
和 vals2
中不相等的一个元素的索引,字符串列表中对应的元素 names
,以及 [=13= 中的对应元素].这是我为此任务编写的函数:
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]])
为了
vals1=[12, 2, 2, 7, 5]
vals2=[12, 5, 2, 7, 15]
names=['a','b','c','d','e']
compareLists
将 return
[('b', 1, 2), ('e', 4, 5)]
该函数有效,但我想知道是否有更有效的方法(更 pythonic 的方法)。任何帮助将不胜感激。
我觉得你的方法没有问题。
或者,您可以使用 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'
如果你有Python >=3.8,你也可以把上面的写成一行(虽然可读性差很多):
out = out if (out:= [(n, idx, i) for idx, (i, j, n) in enumerate(zip(vals1, vals2, names)) if i!=j]) else 'equal'
输出:
[('b', 1, 2), ('e', 4, 5)]
我们也可以写一个 genexp(感谢@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)
我建议使用 enumerate()
而不是 range()
。您还可以删除函数中的 else
,因为它是多余的:
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))
我有三个列表:vals1
、vals2
和 names
。 names
仅包含字符串,而其他两个列表(vals1
、vals2
)仅包含数字。三个列表的长度总是相同的。我的目标是编写一个函数,根据比较结果比较 vals1
和 vals2
和 return 消息或列表。如果 vals1
和 vals2
相等,则函数 return 是一条消息,表明两个列表相等。列表比较必须以保留的顺序进行。例如,vals1 = [1,2,3,2]
不等于 vals2 = [1,2,2,3]
。如果两个数字列表(vals1
和 vals2
)不相等,函数将 return 一个包含元组的列表。此列表中的每个元组包含 vals1
和 vals2
中不相等的一个元素的索引,字符串列表中对应的元素 names
,以及 [=13= 中的对应元素].这是我为此任务编写的函数:
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]])
为了
vals1=[12, 2, 2, 7, 5]
vals2=[12, 5, 2, 7, 15]
names=['a','b','c','d','e']
compareLists
将 return
[('b', 1, 2), ('e', 4, 5)]
该函数有效,但我想知道是否有更有效的方法(更 pythonic 的方法)。任何帮助将不胜感激。
我觉得你的方法没有问题。
或者,您可以使用 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'
如果你有Python >=3.8,你也可以把上面的写成一行(虽然可读性差很多):
out = out if (out:= [(n, idx, i) for idx, (i, j, n) in enumerate(zip(vals1, vals2, names)) if i!=j]) else 'equal'
输出:
[('b', 1, 2), ('e', 4, 5)]
我们也可以写一个 genexp(感谢@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)
我建议使用 enumerate()
而不是 range()
。您还可以删除函数中的 else
,因为它是多余的:
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))