Python:元组过滤器
我有两个元组列表。我想要一个新的列表,其中包含l2的每个成员和l1的每个成员,这些成员不以l2中的相同元素开头 我使用了for循环,输出正常 我的问题是:如何使用筛选函数或列表理解Python:元组过滤器,python,filter,tuples,Python,Filter,Tuples,我有两个元组列表。我想要一个新的列表,其中包含l2的每个成员和l1的每个成员,这些成员不以l2中的相同元素开头 我使用了for循环,输出正常 我的问题是:如何使用筛选函数或列表理解 def ov(l1, l2): l3=l1.copy() for i in l2: for j in l1: if i[0]==j[0]: l3.pop(l3.index(j)) print (l3+l2)
def ov(l1, l2):
l3=l1.copy()
for i in l2:
for j in l1:
if i[0]==j[0]:
l3.pop(l3.index(j))
print (l3+l2)
ov([('c','d'),('c','e'),('a','b'),('a', 'd')], [('a','c'),('b','d')])
输出为:
[('c', 'd'), ('c', 'e'), ('a', 'c'), ('b', 'd')]
如果我理解正确,这应该是直截了当的解决方案:
>>> l1 = [('c','d'),('c','e'),('a','b'),('a', 'd')]
>>> l2 = [('a','c'),('b','d')]
>>>
>>> starters = set(x for x, _ in l2)
>>> [(x, y) for x, y in l1 if x not in starters] + l2
[('c', 'd'), ('c', 'e'), ('a', 'c'), ('b', 'd')]
这可以推广到使用较长的元组
下面是一种使用
过滤器的方法:
from operator import itemgetter
f = itemgetter(0)
zval = set(map(itemgetter(0), l2))
list(filter(lambda tup: f(tup) not in zval, l1)) + l2
[('c', 'd'), ('c', 'e'), ('a', 'c'), ('b', 'd')]
或:
Filter是一个函数,它返回函数的所有真返回的列表,用作过滤器(function(),迭代器)
我做这件事是为了做这件事。Lambda可能有点混乱,如果你不理解它,请保持警惕,我会重新制作它
列表理解是一个“三元运算符”,如果你熟悉的话,为了在一行中列出一个列表
l1 = [('c','d'),('c','e'),('a','b'),('a', 'd')]
l2 = [('a','c'),('b','d')]
l3 = [l1[n] for n in range(len(l1)) if l1[n][0] not in [l2[i][0] for i in range(len(l2))]]+l2
print(l3)
这段代码可以做到这一点,但一开始是压倒性的。让我解释一下它的作用。
l1[n]表示范围内的n(len(l1)
遍历l1中的所有对,以查看是否可以添加它们。这是在if返回True时完成的。
l1[n][0]不在
中取第一项,如果在以下列表的任何元素中不存在,则返回True。
[l2[i][0]for i in range(len(l2))]
从l2的所有第一个元素创建一个列表。
根据要求添加+l2
作为奖励,我将解释如何在同一场景中使用else,以防您需要另一个结果
l1 = [('c','d'),('a','b'),('c','e'),('a', 'd')]
l2 = [('a','c'),('b','d')]
l3 = [l1[n] if l1[n][0] not in [l2[i][0] for i in range(len(l2))] else ("not", "you") for n in range(len(l1))]+l2
print(l3)
正如您所看到的,我必须切换操作符的顺序,但是按照它应该的方式工作,以l1的正确顺序添加它们(为了显示,我更改了顺序)
我无法测试,但在for
循环中,索引
和弹出
发出警报。这在其他示例中是否可靠工作?如果我理解正确,可以通过使用(有序)字典轻松解决:d=dict(l1);d.update(l2)
。如有必要,您可以将字典转换回元组列表。@roganjosh我很感激您的提醒。我尝试了一些其他示例,效果很好。我建议将f=itemgetter(0)
作为第一行,然后在整个过程中使用f
。为什么要使用range(len())
什么时候可以在理解中使用元组解包?老实说,这是C语言的老习惯。不过,这是一个较低的级别,让初学者能够理解列表是如何工作的。实际上,我也会使用解包。你有('not','you')
在您的最终输出中,我还认为您的方法不适合初学者,因为它不太容易阅读。对初学者来说,更深层次的理解总是更好的,因为它可以避免以后出现问题。我已经解释了所有代码的作用,如果读者不清楚,可以对它们进行重新表述。你说“不”是什么意思,“你”)?看看你在图片中发布的输出,你能更好地解释一下x代表x,在l2
中的含义吗?@PedroPinto它是元组解包。我本可以写set(x代表x,y代表l2)
,但按照惯例
是用来表示“这个名字不会被使用”。
def compare(one, two):
for i in two:
if i[0]==one[0]:
print("yes:", one,two)
return False
return True
l1 = [('c','d'),('c','e'),('a','b'),('a', 'd')]
l2 = [('a','c'),('b','d')]
one_liner = lambda n: compare(l1[n], l2) # where n is the tuple in the first list
lets_filter = list(filter(one_liner, range(len(l1))))
final_list = l2.copy()
for i in lets_filter:
final_list.append(l1[i])
print(final_list)
l1 = [('c','d'),('c','e'),('a','b'),('a', 'd')]
l2 = [('a','c'),('b','d')]
l3 = [l1[n] for n in range(len(l1)) if l1[n][0] not in [l2[i][0] for i in range(len(l2))]]+l2
print(l3)
l1 = [('c','d'),('a','b'),('c','e'),('a', 'd')]
l2 = [('a','c'),('b','d')]
l3 = [l1[n] if l1[n][0] not in [l2[i][0] for i in range(len(l2))] else ("not", "you") for n in range(len(l1))]+l2
print(l3)