集合(set)を使うと、両方・片方に存在する要素の取り出しは
python
1 a = set ( [ "a1" , "b4" , "f2" ] )
2 b = set ( [ "a1" , "a5" , "f2" ] )
3
4 # 順序は不定
5 print ( a | b ) # {"a5", "f2", "b4", "a1}
6 print ( a & b ) # {"f2", "a1"}
7 print ( a - b ) # {"b4"}
8 print ( b - a ) # {"a5"}
のように記述できます。
python
1 a = [ "a1" , "b4" , "f2" ]
2 b = [ "a1" , "a5" , "f2" ]
3
4 def full_outer_join ( * args ) :
5 # リストの平坦化 chain([1,2], [3,4]) => [1,2,3,4]
6 from itertools import chain
7
8 # 集合のリストに変換 `value in list` -> `value in set` の効率化 O(n) -> O(1) を期待
9 # [{"a1", "b4", "f2"},
10 # {"a1", "a5", "f2"}]
11 xs = list ( map ( set , args ) )
12
13 # 結合 {"a1", "b4", "a5", "f2"}
14 for key in sorted ( set ( chain ( * xs ) ) ) :
15 yield (
16 # 引数に与えられたグループ内での存在チェック
17 # null 値は未定義なので、とりあえずここでは表示側で楽できるように空文字
18
19 ( key if key in x else "" ) for x in xs
20 )
21
22 for x , y in full_outer_join ( a , b ) :
23 print ( f" { x : 10 } { y : 10 } " )
24
25
26 c = [ "c1" , "a5" ]
27 for x , y , z in full_outer_join ( a , b , c ) :
28 print ( f" { x : 10 } { y : 10 } { z : 10 } " )
汎用的な処理に落とし込むと
キーの一覧を抽出 {"a1", "b4", "a5", "f2"}
集合(set) で重複を省き、sorted で並べ替え。
実装例としては集合の他に、辞書やcollections.defaultdict を使う等。方法は様々。