Python: фильтр в кортежах - PullRequest
0 голосов
/ 05 января 2019

У меня есть два списка кортежей. Я хочу новый список с каждым членом 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 голосов
/ 05 января 2019

Вот подход, использующий 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')]
0 голосов
/ 05 января 2019

Фильтр - это функция, которая возвращает список всех истинных возвратов функции, используемой как 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)

Я сделал это как способ сделать это. Лямбда может быть немного запутанной, будьте бдительны, если вы этого не понимаете, и я переделаю это.

Понимание списка - это «троичный оператор», если вы с ним знакомы, для составления списка в одну строку.

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 добавляется по запросу.

В качестве бонуса я собираюсь объяснить, как использовать другое в том же сценарии, если вы хотите получить другой результат.

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

0 голосов
/ 05 января 2019

Если я правильно понимаю, это должно быть прямым решением:

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

Это можно обобщить для работы с более длинными кортежами с расширенной итерационной распаковкой .

>>> 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')]
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...