通过索引列表置换元组

时间:2014-11-16 16:10:44

标签: python tuples

我有一个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

3 个答案:

答案 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)