假设我们正在对物品的颜色进行分类。然后创建一个字典d,将每种颜色映射到 A 中具有该颜色的项目列表。然后遍历列表 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
,但这只是实现的产物:通过使用 acollections.deque
代替列表(而popleft
不是pop
),我们可以安排获取相应的元素的A
原始顺序,如果这是首选的话。