Внутреннее соединение 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)] 
  • Почему (()) равно ()?
  • Клиент ntp в python
  • Python the Hard Way - упражнение 6 -% r против% s
  • IndentationError: ожидается отложенный блок, python (if / else)
  • Python, вопрос начинающего! Репозиторий или объект сохраняются?
  • RuntimeError: «list» должен быть None или list, а не <class 'str'> при попытке запустить работника сельдерея
  • Получите разницу между двумя списками в Python
  • область доступа переменной для цикла
  • Pycharm - Как получить доступ к панели «Часы»?
  • Заменяет ли перезагрузка модуль именами в ранее импортированном / перезагруженном модуле?
  • Библиотека для создания URL-адресов в Python
  • Python - лучший язык программирования в мире.