我喜欢其他例子(从他们身上学到了一些东西)。我的回答有点不同:它首先将 x 项转换为 (index, x[index]) 元组,根据元组中的第二项对此类列表进行排序,将索引作为列表取出并使用从y 列表中选择值的索引。
如果有更多类似y 的列表应根据列表x 中的项目顺序排序,这种方法可能会变得有效。
精简版
>>> x = [0, 7, 2, 4, 6, 9, 5]
>>> y = [1, 2, 3, 4, 5, 6, 7]
>>> from operator import itemgetter
>>> pick_0 = itemgetter(0)
>>> pick_1 = itemgetter(1)
>>> x_decor = sorted(enumerate(x), key=pick_1)
>>> x_idxs = map(pick_0, x_decor)
>>> multi_picker = itemgetter(*x_idxs)
>>> multi_picker(y)
(1, 3, 4, 7, 5, 2, 6)
让我解释一下,它是如何工作的,以及为什么它在某些情况下可能是相关的。
装饰、排序、获取索引、使用它们来挑选结果项
首先,获取要使用的值:
>>> x = [0, 7, 2, 4, 6, 9, 5]
>>> y = [1, 2, 3, 4, 5, 6, 7]
然后使用enumerate用列表x中的项目索引来装饰值:
>>> x_decor = [(idx, val) for idx, val in enumerate(x)]
>>> x_decor
[(0, 0), (1, 7), (2, 2), (3, 4), (4, 6), (5, 9), (6, 5)]
根据值对修饰列表进行排序(现在itm[1] 因为itm[0] 是原始位置索引):
>>> x_decor.sort(key=lambda itm: itm[1])
>>> x_decor
[(0, 0), (2, 2), (3, 4), (6, 5), (4, 6), (1, 7), (5, 9)]
最后只列出与排序的x相关的位置索引:
>>> x_idxs = [idx for idx, val in x_decor]
>>> x_idxs
[0, 2, 3, 6, 4, 1, 5]
现在我们使用x_idxs 从y 列表中挑选相关项目:
>>> y_vals = [y[idx] for idx in x_idxs]
>>> y_vals
[1, 3, 4, 7, 5, 2, 6]
可以为其他列表重复最后一步(如果我们有的话)。
使用itemgetter的优化版
可以使用itemgetter 优化以前的代码(提高速度)。
itemgetter 能够创建一个函数,允许从特定位置选取值。 itemgetter 还可以创建函数,允许一次从预定义的位置选择多个值。
>>> from operator import itemgetter
>>> itemgetter(0)
<operator.itemgetter at 0x7f8e300afd90>
>>> pick_0 = itemgetter(0)
>>> pick_1 = itemgetter(1)
>>> pick_0_2 = itemgetter(0, 2)
让我们看看,这些函数能为我们做什么:
>>> pick_0(["a", "b", "c"])
'a'
>>> pick_1(["a", "b", "c"])
'b'
>>> pick_0_2(["a", "b", "c"])
('a', 'c')
让我们像以前一样创建修饰的x,这次使用更短的语法:
>>> x_decor = sorted(enumerate(x), key=pick_1)
>>> x_decor
[(0, 0), (2, 2), (3, 4), (6, 5), (4, 6), (1, 7), (5, 9)]
enumerate(x) 创建修饰列表, sorted 使用 key=pick_1 根据原始 x 列表中的值对其进行排序。
使用pick_0,我们可以从修饰列表中获取索引列表:
>>> x_idxs = map(pick_0, x_decor)
>>> x_idxs
[0, 2, 3, 6, 4, 1, 5]
这些索引可用于创建multi_picker(类似于上面的pick_0_2):
>>> multi_picker = itemgetter(*x_idxs)
>>> multi_picker
<operator.itemgetter at 0x7f8e300afb10>
并使用multi_picker 从列表y 中获取正确排序的元素:
>>> y_vals = multi_picker(y)
>>> y_vals
(1, 3, 4, 7, 5, 2, 6)
如果我们要根据已排序的x 元素对更多列表进行排序,那么multi_picker 将是现在唯一调用它们的函数。