集合(set)を使うと、両方・片方に存在する要素の取り出しは
python
1a = set(["a1","b4","f2"])
2b = set(["a1","a5","f2"])
3
4 # 順序は不定
5print(a | b) # {"a5", "f2", "b4", "a1}
6print(a & b) # {"f2", "a1"}
7print(a - b) # {"b4"}
8print(b - a) # {"a5"}
のように記述できます。
python
1a = ["a1","b4","f2"]
2b = ["a1","a5","f2"]
3
4def 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
22for x, y in full_outer_join(a, b):
23 print(f"{x:10} {y:10}")
24
25
26c = ["c1", "a5"]
27for 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 を使う等。方法は様々。