I have a 3 element python tuple that I'm trying to sort or re-arrange using the indices of a 3-element list, and I want to know what the most concise way to do this is.
So far I've got:
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)
I also get the same result if I do:
my_shuffled_tuple = tuple([my_tuple[i] for i in new_positions])
Is there a more concise way to create my_shuffled_tuple
?
One way to do this is with a generator expression as an argument to tuple
, which 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)
If speed is an issue and you are working with a large amount of data, you should consider using Numpy. This allows direct indexing with a list or array of indices:
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])
You can use operator.itemgetter
like this:
from operator import itemgetter
my_tuple = (10, 20, 30)
new_positions = [2, 0, 1]
print itemgetter(*new_positions)(my_tuple)
If you will be accessing the elements of my_tuple
(or other things too) in the new ordering a lot, you can save this itemgetter
as a helper function:
access_at_2_0_1 = itemgetter(*new_positions)
and then access_at_2_0_1(foo)
will be the same as tuple(foo[2], foo[0], foo[1])
.
This is very helpful when you are trying to work with an argsort-like operation (where lots of arrays need to be re-accessed in a sort order that comes from sorting some other array). Generally, by that point you should probably be using NumPy arrays, but still this is a handy approach.
Note that as itemgetter
relies on the __getitem__
protocol (derp) it is not guaranteed to work with all types of iterables, if that is important.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With