Внутреннее соединение SQL-стиля в Python?

У меня есть два массива:

[('a', 'beta'), ('b', 'alpha'), ('c', 'beta'), .. ] [('b', 37), ('c', 22), ('j', 93), .. ] 

Я хочу создать что-то вроде:

 [('b', 'alpha', 37), ('c', 'beta', 22), .. ] 

Есть простой способ сделать это?

2 Solutions collect form web for “Внутреннее соединение SQL-стиля в Python?”

Я бы предложил, чтобы дискриминатор хеша соединялся как метод:

 l = [('a', 'beta'), ('b', 'alpha'), ('c', 'beta')] r = [('b', 37), ('c', 22), ('j', 93)] d = {} for t in l: d.setdefault(t[0], ([],[]))[0].append(t[1:]) for t in r: d.setdefault(t[0], ([],[]))[1].append(t[1:]) from itertools import product ans = [ (k,) + l + r for k,v in d.items() for l,r in product(*v)] 

результаты:

 [('c', 'beta', 22), ('b', 'alpha', 37)] 

Это имеет более низкую сложность ближе к O (n + m), чем O (nm), поскольку она позволяет избежать вычисления product(l,r) а затем фильтровать как наивный метод.

В основном из: Реляционная алгебра Fritz Henglein с дискриминационными объединениями и ленивыми продуктами

Его также можно записать в виде:

 def accumulate(it): d = {} for e in it: d.setdefault(e[0], []).append(e[1:]) return d l = accumulate([('a', 'beta'), ('b', 'alpha'), ('c', 'beta')]) r = accumulate([('b', 37), ('c', 22), ('j', 93)]) from itertools import product ans = [ (k,) + l + r for k in l&r for l,r in product(l[k], r[k])] 

Это накапливает оба списка отдельно (превращает [(a,b,...)] в {a:[(b,...)]} ), а затем вычисляет пересечение между их наборами ключей. Это выглядит чище. если l&r не поддерживается между словарями, замените его на set(l)&set(r) .

Нет встроенного метода. Я полагаю, добавление пакета, такого как numpy , даст дополнительные функциональные возможности.

Но если вы хотите решить проблему без использования каких-либо дополнительных пакетов, вы можете использовать один лайнер следующим образом:

 ar1 = [('a', 'beta'), ('b', 'alpha'), ('c', 'beta')] ar2 = [('b', 37), ('c', 22), ('j', 93)] final_ar = [tuple(list(i)+[j[1]]) for i in ar1 for j in ar2 if i[0]==j[0]] print(final_ar) 

Вывод:

 [('b', 'alpha', 37), ('c', 'beta', 22)] 
  • Почему я не могу солить этот объект?
  • Использование и значение «in» в выражении if?
  • Получить исходное имя файла Google
  • Объекты GAE put_multi (), использующие backend NDB
  • удаление элементов из списка
  • Воспроизведение команды Unix cat в Python
  • При доступе к Bigquery с использованием API Python в чем отличие использования API-интерфейса google и gcloud
  • Плагин IntelliJ Python & Run classpath
  • Python - лучший язык программирования в мире.