我有两个元组列表。我想要一个新列表,其中包含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)
ov([('c','d'),('c','e'),('a','b'),('a', 'd')], [('a','c'),('b','d')])
输出为:
[('c', 'd'), ('c', 'e'), ('a', 'c'), ('b', 'd')]
答案 0 :(得分:4)
如果我理解正确,这应该是直接的解决方案:
>>> 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')]
这可以推广到使用extended iterable unpacking处理更长的元组。
>>> starters = set(head for head, *_ in l2)
>>> [(head, *tail) for head, *tail in l1 if head not in starters] + l2
[('c', 'd'), ('c', 'e'), ('a', 'c'), ('b', 'd')]
答案 1 :(得分:2)
以下是使用filter
的方法:
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')]
或者:
def parser(tup):
return f(tup) not in zval
list(filter(parser, l1)) + l2
[('c', 'd'), ('c', 'e'), ('a', 'c'), ('b', 'd')]
答案 2 :(得分:0)
过滤器是一个函数,它返回一个函数的所有True返回的列表,用作filter(function(), iterator)
。
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)
我这样做是这样做的一种方式。 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] for n in range(len(l1)
遍历l1中的所有对,以查看是否可以添加它们。如果if返回True,则完成此操作。
l1[n][0] not in
接受第一项,如果以下列表的任何元素中不存在,则返回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的正确顺序添加它们(为显示起见,我对其进行了更改)。