先日は、dict リスト の結合だったので今度は、tupleリストの結合
a = [ ('A',1103),('B',1104),('C',1105) ] b = [ ('A','red'),('C','yellow'),('D','blue') ]
先頭インデックス [0] をキーとして結合する。
それぞれキーのdict を用意する
a_dict = { t[0]:t for t in a } b_dict = { t[0]:t for t in b }
以下のように set を使う方法は、順番が定まらないので tuple として使用できない
c = [ tuple(set(at + b_dict.get(at[0],(None,None)))) for at in a ]
結合で生成する tuple タプルは、+ 演算子以外に更新する方法がないので、
+ 演算子以外の方法として、一時的に list に変換してからマージするメソッドを
用意する
# tuple をマージするメソッド def mergeTuple(t, u): x = list(t) for i in range(len(t)-1): x.append(None if u[i] is None else u[i+1]) return tuple(x)
a LEFT JOIN b ON a[0] = b[0]
# a ← b a_left_b = [ mergeTuple(at, b_dict.get(at[0], (None,None))) for at in a ]
b LEFT JOIN a ON b[0] = a[0]
# b ← a b_left_a = [ mergeTuple(bt, a_dict.get(bt[0], (None,None))) for bt in b ]
a LEFT JOIN b ON a[0] = b[0] WHERE b[2] NOT NULL
# a ← b where color is not null a_left_b_C = list(filter(lambda x:x[2] is not None, [ mergeTuple(at, b_dict.get(at[0], (None,None))) for at in a ]))
b LEFT JOIN a ON b[0] = a[0] WHERE a[2] NOT NULL
# b ← a where color is not null b_left_a_C = list(filter(lambda x:x[2] is not None, [ mergeTuple(bt, a_dict.get(bt[0], (None,None))) for bt in b ]))
print(a_dict) print(b_dict) print('\n-- a LEFT JOIN b ON a.name=b.name --') print(a_left_b) print('\n-- b LEFT JOIN a ON b.name=a.name --') print(b_left_a) print('\n-- a LEFT JOIN b ON a.name=b.name WHERE color is not null --') print(a_left_b_C) print('\n-- b LEFT JOIN a ON b.name=a.name WHERE id not null --') print(b_left_a_C)
print の結果
{'A': ('A', 1103), 'B': ('B', 1104), 'C': ('C', 1105)} {'A': ('A', 'red'), 'C': ('C', 'yellow'), 'D': ('D', 'blue')} -- a LEFT JOIN b ON a.name=b.name -- [('A', 1103, 'red'), ('B', 1104, None), ('C', 1105, 'yellow')] -- b LEFT JOIN a ON b.name=a.name -- [('A', 'red', 1103), ('C', 'yellow', 1105), ('D', 'blue', None)] -- a LEFT JOIN b ON a.name=b.name WHERE color is not null -- [('A', 1103, 'red'), ('C', 1105, 'yellow')] -- b LEFT JOIN a ON b.name=a.name WHERE id not null -- [('A', 'red', 1103), ('C', 'yellow', 1105)]