taylormade201
taylormade201

Reputation: 706

Sort python list with order of another, larger list

I have 2 lists, for example:

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

I would like to sort the common elements in list b by the order of list a, to get something like this:

['a','c','dog']

I have read similar questions using sorted(), however I cannot make it work when the lists do not contain the same elements (i.e. 'dog' in list b).

Upvotes: 0

Views: 137

Answers (4)

verbsintransit
verbsintransit

Reputation: 908

You could use (frozen) sets. I have not timed this against other answers.

>>> a = ['a','b','c','d','e']
>>> b = ['c','a','dog']
>>> list((frozenset(a)^frozenset(b))^frozenset(a))
['a', 'c', 'dog']

Upvotes: 0

iruvar
iruvar

Reputation: 23394

One option is to use bisect

import bisect
from operator import itemgetter
a = ['a','b','c','d','e']
b = ['c','a','dog']
l = sorted([(x, bisect.bisect(a, x)) for x in b], key=itemgetter(1))
l = [x[0] for x in l]
print l
['a', 'c', 'dog']

Upvotes: 0

Martijn Pieters
Martijn Pieters

Reputation: 1125078

I'd turn a into dictionary:

a_dict = dict((v, i) for i, v in enumerate(a))

and use float('inf') to indicate values to be sorted at the end:

sorted(b, key=lambda v: a_dict.get(v, float('inf')))

Demo:

>>> a = ['a','b','c','d','e']
>>> b = ['c','a','dog']
>>> a_dict = dict((v, i) for i, v in enumerate(a))
>>> sorted(b, key=lambda v: a_dict.get(v, float('inf')))
['a', 'c', 'dog']

This has the advantage of speed; dict lookups are O(1) versus list .index() lookups having a O(n) cost. You'll notice this more as a and b grow in size.

The disadvantage is that duplicate values in a are handled differently; the dict approach picks the last index versus .index() picking the first.

Upvotes: 2

Ashwini Chaudhary
Ashwini Chaudhary

Reputation: 251186

>>> a = ['a','b','c','d','e']
>>> b = ['c','a','dog']
>>> def func(x):
...     try:
...         return a.index(x)
...     except ValueError:
...         return float("inf")
...     
>>> sorted(b, key = func)
['a', 'c', 'dog']

Upvotes: 4

Related Questions