# An ordering question

andrew cooke andrew at acooke.org
Fri Mar 13 19:33:27 CET 2009

```Hrvoje Niksic wrote:
> Kottiyath <n.kottiyath at gmail.com> writes:
>
>> Hi,
>>     I have 2 lists
>> a = [(4, 1), (7, 3), (3, 2), (2, 4)]
>> b = [2, 4, 1, 3]
>>
>>     Now, I want to order _a_ (a[1]) based on _b_.
>>     i.e. the second element in tuple should be the same as b.
>>     i.e. Output would be [(3, 2), (2, 4), (4, 1), (7, 3)]
> [...]
>>      whether I can do it in a line or 2,
>
> a.sort(key=lambda (x, y): b[y - 1], reverse=True)

that's hilarious!  i have no idea how it works, but unfortunately it's not
general:

>>> a = [(4, 1), (7, 3), (3, 2), (2, 4)]
>>> b = [4, 2, 1, 3]
>>> a.sort(key=lambda xy: b[xy[1] - 1], reverse=True)
>>> a
[(4, 1), (2, 4), (3, 2), (7, 3)]

(in 3.0 there's no unpacking in function args)

did you just play around until you got the right answer?  how many
different tries did you need?

the answer i think the original person was looking for is:

>>> a = [(4, 1), (7, 3), (3, 2), (2, 4)]
>>> b = [2, 4, 1, 3]
>>> a.sort(key=lambda xy: b.index(xy[1]))
>>> a
[(3, 2), (2, 4), (4, 1), (7, 3)]

>>> a = [(4, 1), (7, 3), (3, 2), (2, 4)]
>>> b = [4, 2, 1, 3]
>>> a.sort(key=lambda xy: b.index(xy[1]))
>>> a
[(2, 4), (3, 2), (4, 1), (7, 3)]

however, it's not very efficient.  it would be better to do:

>>> a = [(4, 1), (7, 3), (3, 2), (2, 4)]
>>> b = [4, 2, 1, 3]
>>> idx = dict((b[i], i) for i in range(len(b)))
>>> a.sort(key=lambda xy: idx[xy[1]])
>>> a
[(2, 4), (3, 2), (4, 1), (7, 3)]

for large lists

andrew

```