简体   繁体   English

Python:筛选元组

[英]Python: Filter in tuples

I have two lists of tuples. 我有两个元组列表。 I want a new list with every member of l2 and every member of l1 that does not begin with the same element from l2. 我想要一个新列表,其中包含l2的每个成员和l1的每个成员,且该列表不以l2中的相同元素开头。

I used a for loop and my output is ok. 我使用了for循环,输出正常。

My question is: How can I use the filter function or a list comprehension? 我的问题是:如何使用过滤器功能或列表理解?

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')])

The output is: 输出为:

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

If I understand correctly, this should be the straight forward solution: 如果我理解正确,那么这应该是直接的解决方案:

>>> 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')]

This can be generalized to work with longer tuples with 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')]

Here is an approach using filter : 这是使用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')]

Or: 要么:

def parser(tup):
    return f(tup) not in zval

list(filter(parser, l1)) + l2

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

Filter is a function which returns a list for all True returns of a function, being used as filter(function(), iterator) . Filter是一个函数,它返回函数的所有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)

I made this as a way to do it. 我这样做是这样做的一种方式。 Lambda might be a bit confusing, alert if you don't understand it, and I'll remake it. Lambda可能有点令人困惑,如果您不了解它,请提醒我,我会重做。

List comprehension is a "ternary operator", if you're familiar with those, in order to make a list in a one-liner. 列表理解是一种“三元运算符”(如果您熟悉的话),以便在单行中创建列表。

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)

This code does the trick, but is overwhelming at first. 这段代码可以解决问题,但起初是令人头晕的。 Let me explain what it does. 让我解释一下它的作用。 l1[n] for n in range(len(l1) goes through all the pairs in l1, in order to see if we can add them. This is done when the if returns True. l1[n][0] not in takes the first item, and returns True if doesn't exist in any of the elements of the following list. [l2[i][0] for i in range(len(l2))] makes a list from all the first elements of l2. +l2 is added, as requested. l1[n] for n in range(len(l1)遍历l1[n] for n in range(len(l1)所有对,以查看是否可以添加它们。当if返回True时完成l1[n][0] not in第一项,如果以下列表的任何元素中不存在,则返回True; [l2[i][0] for i in range(len(l2))]从列表的所有前一个元素组成一个列表l2。根据需要添加+l2

As a bonus, I'm going to explain how to use else in the same scenario, in case you wanted another result. 另外,如果您想要另一个结果,我将解释在相同情况下如何使用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)

As you can see, I had to switch the order of the operators, but works as it should, adding them in the correct order of l1 (which I changed for the sake of showing). 如您所见,我不得不切换运算符的顺序,但是按其应有的方式工作,以l1的正确顺序添加它们(为了显示,我对其进行了更改)。

Python脚本

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM