Python:筛选元组

时间:2019-01-04 23:29:00

标签: 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)            

ov([('c','d'),('c','e'),('a','b'),('a', 'd')], [('a','c'),('b','d')])

输出为:

[('c', 'd'), ('c', 'e'), ('a', 'c'), ('b', 'd')]

3 个答案:

答案 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的正确顺序添加它们(为显示起见,我对其进行了更改)。

Python script

相关问题