アイテムの色でソートしているとします。次に、各色をその色を持つ A の項目のリストにマップする辞書dを作成します。次に、リスト B の色を反復処理し、色cごとに、リストd [ c ]から値を出力 (および削除) します。これは O( n ) 時間で実行され、O( n )辞書用の余分なスペースが必要です。
B の例に従って A をソートできない場合にどうするかを決定する必要があることに注意してください: エラーを発生させますか? 一致数が最大になる順序を選択しますか? または何?
とにかく、Python での簡単な実装を次に示します。
from collections import defaultdict
def sorted_by_example(A, B, key):
"""Return a list consisting of the elements from the sequence A in the
order given by the sequence B. The function key takes an element
of A and returns the value that is used to match elements from B.
If A cannot be sorted by example, raise IndexError.
"""
d = defaultdict(list)
for a in A:
d[key(a)].append(a)
return [d[b].pop() for b in B]
>>> A = [{'id': 1, 'color': 'red'}, {'id': 2, 'color': 'green'}, {'id': 3, 'color': 'blue'}]
>>> B = ['green', 'blue', 'red']
>>> from operator import itemgetter
>>> sorted_by_example(A, B, itemgetter('color'))
[{'color': 'green', 'id': 2}, {'color': 'blue', 'id': 3}, {'color': 'red', 'id': 1}]
このアプローチは、シーケンス B に複数の同一の値がある場合を処理することに注意してください。次に例を示します。
>>> A = 'proper copper coffee pot'.split()
>>> B = 'ccpp'
>>> ' '.join(sorted_by_example(A, B, itemgetter(0)))
'coffee copper pot proper'
ここで、 に複数の同一の値がある場合B
、対応する要素をA
逆の順序で取得しますが、これは単なる実装のアーティファクトです:collections.deque
リストの代わりに (および のpopleft
代わりにpop
) を使用することで、対応する要素を取得するように調整できます。A
元の順序が望ましい場合は、元の順序で。