1

I have two list x and y. The former is always longer than or equal to the latter.

x = ["foo","bar","qux","zox"]
y1 = ["zox", "qux","foo"]

What I want to do is to sort y1 based on the order of x. Yielding

["foo","qux","zox"]

I tried this, but doesn't work:

In [10]: [x[1] for x in sorted(zip(x,y))]
Out[10]: ['zox', 'qux']

What's the right way to do it?

1
  • zipping isn't exactly going to yield anything close to what they were asking for. Commented Mar 18, 2015 at 1:50

4 Answers 4

4

You can use the key argument of sorted to use the index from the first list.

>>> sorted(y1, key=x.index)
['foo', 'qux', 'zox']
Sign up to request clarification or add additional context in comments.

Comments

2

Just iterate through each element in x and add that element to a new list only if the corresponding element exists in y1.

>>> x = ["foo","bar","qux","zox"]
>>> y1 = ["zox", "qux","foo"]
>>> l = []
>>> for i in x:
        if i in y1:
            l.append(i)


>>> l
['foo', 'qux', 'zox']

OR

Use list_comprehension.

>>> [i for i in x if i in y1]
['foo', 'qux', 'zox']

Comments

1

Note that depending how large your list is .index requires a linear scan, and can be expensive. You may just create a one off dictionary of key->last index, and then use that as a reference to sort:

x = ["foo","bar","qux","zox"]
y1 = ["zox", "qux","foo"]

y1.sort(key=lambda L, d={k:i for i,k in enumerate(x)}: d[L])
# ['foo', 'qux', 'zox'] 

However, you could also do it the other way around, which could well be more efficient... Convert y1 to set then only keep elements also in x, eg:

filter(set(y1).__contains__, x)

Comments

0

You can also define a custom comparator for when sorting, like so:

x = ["foo","bar","qux","zox"]
y1 = ["zox", "qux","foo"]

def foo_sort(a,b):
   return x.index(a)-x.index(b)
y1.sort(cmp=foo_sort)

print y1

Gives:

['foo', 'qux', 'zox']

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.