我有一个3元素的python元组,我正在尝试使用3元素列表的索引进行排序或重新排列,我想知道最简洁的方法是什么。
到目前为止,我已经:
my_tuple = (10, 20, 30)
new_positions = [2, 0, 1]
my_shuffled_tuple = my_tuple[new_positions[0]], my_tuple[new_positions[1]], my_tuple[new_positions[2]]
# outputs: (30, 10, 20)
如果我这样做,我也会得到相同的结果:
my_shuffled_tuple = tuple([my_tuple[i] for i in new_positions])
是否有更简洁的方法来创建my_shuffled_tuple
?
答案 0 :(得分:5)
执行此操作的一种方法是使用generator expression作为tuple
的参数,accepts an iterable:
In [1]: my_tuple = (10, 20, 30)
...: new_positions = [2, 0, 1]
...:
In [2]: my_shuffled_tuple = tuple(my_tuple[i] for i in new_positions)
In [3]: my_shuffled_tuple
Out[3]: (30, 10, 20)
如果速度是一个问题并且您正在处理大量数据,则应考虑使用Numpy。这允许使用列表或索引数组进行直接索引:
In [4]: import numpy as np
In [5]: my_array = np.array([10, 20, 30])
In [6]: new_positions = [2, 0, 1] # or new_positions = np.array([2, 0, 1])
In [7]: my_shuffled_array = my_array[new_positions]
In [8]: my_shuffled_array
Out[8]: array([30, 10, 20])
答案 1 :(得分:3)
您可以像这样使用operator.itemgetter
:
from operator import itemgetter
my_tuple = (10, 20, 30)
new_positions = [2, 0, 1]
print itemgetter(*new_positions)(my_tuple)
如果您要在新订单中访问my_tuple
(或其他东西)的元素,您可以将此itemgetter
保存为辅助函数:
access_at_2_0_1 = itemgetter(*new_positions)
然后access_at_2_0_1(foo)
将与tuple(foo[2], foo[0], foo[1])
相同。
当您尝试使用类似argsort的操作时,这非常有用(其中需要以排序其他数组的排序顺序重新访问大量数组)。通常,到那时你应该使用NumPy数组,但这仍然是一种方便的方法。
请注意,由于itemgetter
依赖于__getitem__
协议(derp),因此不保证可以使用所有类型的迭代,如果这很重要的话。
答案 2 :(得分:2)
在tuple()
内置函数中使用理解(它接受生成器)
>>> my_tuple = (10, 20, 30)
>>> new_positions = [2, 0, 1]
>>> tuple(my_tuple[i] for i in new_positions)
(30, 10, 20)