7

I have a list a:

a = ['c','d','b','a','e']

and a list b:

b = ['a001','b002','c003','d004','e005']

and how could I get my list c as following:

c = ['c003','d004','b002','a001','e005']

Basically sort b using part of each element, by the order defined in a.

Many Thanks.

dli
  • 983
  • 3
  • 10
  • 18

3 Answers3

6

If you have a very big list, the solutions using .index will not be very efficient as the first list will be index'd for each entry in the second list. This will take O(n^2) time.

Instead, you can construct a sort mapping:

order = {v:i for i,v in enumerate(a)}
c = sorted(b, key=lambda x: order[x[0]])
nneonneo
  • 162,933
  • 34
  • 285
  • 360
  • question: how many times is `key` called during a sort? `n`? is there a cache made of key results? – njzk2 Apr 14 '14 at 20:08
  • 3
    @njzk2: IIRC `key` is computed once for each element and stored. This is in contrast to the `cmp` argument, which is evaluated once per comparison. – nneonneo Apr 14 '14 at 20:12
5

You can do it using the key named argument of sorted():

c = sorted(b, key = lambda e: a.index(e[0]))
recursive
  • 80,919
  • 32
  • 145
  • 234
  • This is a bad idea. `index` will perform an _O(N)_ search on `a` resulting in an `O(N² log N)` sort. – Richard Jun 01 '20 at 00:39
  • Sorts are normally said to be `O(N log N)`, where `N` is the number of elements in the list. That's not necessarily the same number as the number of elements in `a`. If `a` is small, then this could be faster than setting up a `dict`. As usual, test the performance using data from your use case. – recursive Jun 01 '20 at 03:24
3

You can try passing a lambda function to the key parameter of the sorted() built-in function:

a = ['c', 'd', 'B', 'a', 'e']
b = ['a001', 'B002', 'c003', 'd004', 'e005']
c = sorted(b, key = lambda x: a.index(x[0])) # ['c003', 'd004', 'b002', 'a001', 'e005']
Christian Tapia
  • 32,670
  • 6
  • 50
  • 72
  • 1
    This is a bad idea. `index` will perform an _O(N)_ search on `a` resulting in an `O(N² log N)` sort. – Richard Jun 01 '20 at 00:38