Alex Rivera | Logout

Given parallel lists, how can I sort one while permuting (rearranging) the other in the same way?

Asked 2012-03-19T02:35:10.007
258

Suppose I have:

list1 = [3, 2, 4, 1, 1]
list2 = ['three', 'two', 'four', 'one', 'one2']

Calling list1.sort() will sort it, resulting in [1, 1, 2, 3, 4]. However, can I get list2 to be rearranged in sync with that, to get a result like this?

list1 = [1, 1, 2, 3, 4]
list2 = ['one', 'one2', 'two', 'three', 'four']

Sometimes, people phrase the problem differently: given two lists, they would like to use one to determine the sort order for the other - i.e., sort list2 in the order described by the corresponding values in list1. The trick is that this is equivalent to sorting the "key" values (list1), and then rearranging list2 in the same way. In other words, exactly what is described here. Some answers for the other question, though, discard the "sorted keys" afterwards.

See also: How can I sort a list, according to where its elements appear in another list? - this is another common way that people want to sort one list "based on" another. Before attempting to close duplicate questions, take special care to check exactly what the OP wants. A key clue: do the lists need to be the same length?

Edit
Report

1 Answer

15

This can be done using what Perl programmers call the Schwartzian transform, also known as the decorate-sort-undecorate idiom. The built-in Python sorting is stable, so the two 1s don't cause a problem.

>>> l1 = [3, 2, 4, 1, 1]
>>> l2 = ['three', 'two', 'four', 'one', 'second one']
>>> zip(*sorted(zip(l1, l2)))
[(1, 1, 2, 3, 4), ('one', 'second one', 'two', 'three', 'four')]
answered 2012-03-19T02:44:33.187

Your Answer