Получить пересечение из списка кортежей

У меня есть два списка кортежей

a = [('head1','a'),('head2','b'),('head3','x'),('head4','z')]
b = [('head5','u'),('head6','w'),('head7','x'),('head8','y'),('head9','z')]

Я хочу взять пересечение 2-го элемента каждого кортежа, например, набор {a[0][0],a[0][1],a[0][2],a[0][3]} пересечение с множеством {b[0][0],b[0][1],b[0][2],b[0][3],b[0][4]} из списка a а также b такой, что он возвращает отображение первого элемента кортежа, если существует значение пересечения. Полученный результат должен выглядеть примерно так:

res = [('head3','head7'),('head4','head9')]

Пока я пробовал это:

x = [(a[i][0],b[j][0]) for i in range(len(a)) for j in range(len(b)) if a[0][i] == b[0][j]]

но получил ошибку IndexError: tuple index out of range

Что может быть правильным и быстрым способом сделать это?

2 ответа

Решение

Вы можете сделать следующее в Python 3. Создать из ваших списков дикты, взяв пересечение ключей из обоих диктов, и получить соответствующие значения у ключа:

>>> da = {k:v for v, k in a}
>>> db = {k:v for v, k in b}
>>> [(da[k], db[k])  for k in da.keys()&db.keys()]
[('head4', 'head9'), ('head3', 'head7')]

В Python 2 вы можете использовать set(da).intersection(db) на месте da.keys()&db.keys(),

Вы можете использовать функцию с генератором:

def pairs():
   a = [('head1','a'),('head2','b'),('head3','x'),('head4','z')]
   b = [('head5','u'),('head6','w'),('head7','x'),('head8','y'),('head9','z')]

   for val1, val2 in a:
       for val3, val4 in b:
           if val2 == val4:
               yield (val1, val3)

print(list(pairs()))

Выход:

[('head3', 'head7'), ('head4', 'head9')]

Вы также можете использовать такое понимание списка

a = [('head1','a'),('head2','b'),('head3','x'),('head4','z')]
b = [('head5','u'),('head6','w'),('head7','x'),('head8','y'),('head9','z')]

pairs = [(val1,val3) for val1,val2 in a for val3,val4 in b if val2 == val4]
print(pairs)
Другие вопросы по тегам