Catherine
Catherine

Reputation: 747

Python: How to sort a list based on another list

I want to order list1 based on the strings in list2. Any elements in list1 that don't correspond to list2 should be placed at the end of the correctly ordered list1.

For example:

list1 = ['Title1-Apples', 'Title1-Oranges', 'Title1-Pear', 'Title1-Bananas']
list2 = ['Bananas', 'Oranges', 'Pear']

list1_reordered_correctly= ['Title1-Bananas','Title1-Oranges','Title1-Pear','Title1-Apples']

Upvotes: 3

Views: 177

Answers (5)

rreddy
rreddy

Reputation: 95

something like this would get you going on this.

l = ['Title1-Apples', 'Title1-Oranges', 'Title1-Pear', 'Title1-Bananas']
l2 = ['Bananas', 'Oranges', 'Pear']
l3 = []
for elem_sub in l2:
    for elem_super in l:
        if elem_sub in elem_super:
            l3.append(elem_super)

print(l3 + list(set(l)-set(l3)))

Upvotes: 0

Andriy Ivaneyko
Andriy Ivaneyko

Reputation: 22021

Use code below to achieve desired sorting:

list1 = ['Title1-Apples', 'Title1-Oranges', 'Title1-Pear', 'Title1-Bananas']
list2 = ['Bananas', 'Pear']

# note: converting to set would improve performance of further look up
list2 = set(list2)

def convert_key(item):
    return int(not item.split('-')[1] in list2)



print sorted(list1, key=convert_key)
#  ['Title1-Pear', 'Title1-Bananas', 'Title1-Apples', 'Title1-Oranges']

Upvotes: 0

Bzisch
Bzisch

Reputation: 101

One liner.

sorted_list = sorted(list1, key=lambda x: list2.index(x.split('-')[1]) if x.split('-')[1] in list2 else len(list2) + 1)

Upvotes: 0

timgeb
timgeb

Reputation: 78650

Here's an idea:

>>> def keyfun(word, wordorder):
...     try:
...         return wordorder.index(word)
...     except ValueError:
...         return len(wordorder)
... 
>>> sorted(list1, key=lambda x: keyfun(x.split('-')[1], list2))
['Title1-Bananas', 'Title1-Oranges', 'Title1-Pear', 'Title1-Apples']

To make it neater and more efficient (index has to traverse the list to find the right item), consider defining your word-order as a dictionary, i.e.:

>>> wordorder = dict(zip(list2, range(len(list2))))
>>> wordorder
{'Pear': 2, 'Bananas': 0, 'Oranges': 1}
>>> sorted(list1, key=lambda x: wordorder.get(x.split('-')[1], len(wordorder)))
['Title1-Bananas', 'Title1-Oranges', 'Title1-Pear', 'Title1-Apples']

Upvotes: 4

Alan
Alan

Reputation: 9610

This answer is conceptual rather than efficient.

st1dict = dict((t.split('-')[1],t) for t in st1) #keys->titles
list2titles = list(st1dict[k] for k in list2)    #ordered titles
extras = list(t for t in st1 if t not in list2titles)  #extra titles
print(list2titles+extras)  #the desired answer

Upvotes: 0

Related Questions