2

Consider this list.

input_list = ['Saturday', 'Tuesday', 'Sunday', 'Monday', 'Thursday', 'Wednesday', 'Cheeseburger', 'Friday']

I want to sort it based on partial matches of a 2nd list.

list_sorter = ['Mon', 'Tue', 'Wed']

so that

output_list = ['Monday', 'Tuesday', 'Wednesday', 'Cheeseburger', 'Friday', 'Saturday', 'Sunday','Thursday']

Storing the sorted list to input_list is preferred. Thanks in advance for the assistance.

Edit:

I've tried sorted(input_list, key = list_sorter.index)

Which errors.

ValueError: 'Saturday' is not in list

I've tried sorted(input_list, key = lambda x: x in list_sorter)

Which is also not correct.

Edit 2: It should not be assumed the text is at the start of the word. Sorry for the late edit, it didn't occur to me until I saw the replies.

list_sorter = ['Mon', 'Tue', 'rida']
output_list = ['Monday', 'Tuesday','Friday','Cheeseburger', 'Saturday', 'Sunday','Thursday','Wednesday']

when there's a partial match on list_sorter should also be supported.

Joylove
  • 414
  • 1
  • 5
  • 20
  • 1
    So, what have you tried? While some answerers might feel generous and answer anyway, you're much more likely to get an answer if you've tried to solve the problem yourself and can show your work (and what is going wrong with it). This question reads like a homework assignment, and Stack Overflow isn't here to do your homework for you. Hint: Try writing a function you can pass as `list.sort`'s `key` parameter. – Blckknght Dec 10 '18 at 18:32
  • 1
    What have you tried so far? Your samples don't make too much sense to me. Please be clear about what you need. – Pedro Lobito Dec 10 '18 at 18:32
  • 1
    it there a rule for words not concerned by list_sorter ? – B. M. Dec 10 '18 at 21:02
  • Words not covered in the list_sorter I would like them to either be sorted alphabetically or preserved order. So I have control of the order. list_sorter ranks the input_list by most important first and remaining words are the same rank. – Joylove Dec 10 '18 at 21:51
  • 1
    @Joylove, I updated my solution; the words not covered are in preserved order. – jpp Dec 10 '18 at 22:08

4 Answers4

2

You can construct a dictionary mapping, then use sorted with dict.__getitem__. This works fine because sorted is a stable sorting algorithm.

sort_map = {day: next((idx for idx, val in enumerate(list_sorter) if val in day),
                 len(input_list)) for day in input_list}

res = sorted(input_list, key=sort_map.__getitem__)

['Monday', 'Tuesday', 'Friday', 'Saturday', 'Sunday',
 'Thursday', 'Wednesday', 'Cheeseburger']
jpp
  • 159,742
  • 34
  • 281
  • 339
  • it works because https://stackoverflow.com/questions/39980323/are-dictionaries-ordered-in-python-3-6; perharps dangerous ? – B. M. Dec 10 '18 at 20:38
  • @B.M., Nope, my solution does not rely on ordering of dictionaries. `sort_map` maps to integers, no `dict` ordering is assumed. – jpp Dec 10 '18 at 20:47
  • Ok I understood. I was troubled because 'Cheeseburger' was at is alphabetic place, but this is a random feature. So no problem. – B. M. Dec 10 '18 at 21:00
1

First make a dictionary with sorting informations in O(len(list_sorter)+len(input_list)):

order=dict.fromkeys([x[:3] for x in input_list],len(list_sorter))
order.update({k:v for (v,k) in enumerate(list_sorter)})
#{'Sat': 3, 'Tue': 1, 'Sun': 3, 'Mon': 0, 'Thu': 3, 'Wed': 2, 'Che': 3, 'Fri': 3}

Then sort:

res=sorted(input_list, key = lambda x : (order[x[:3]],x[:3]))
#['Monday', 'Tuesday', 'Wednesday', 'Cheeseburger', 'Friday', \
#  'Saturday', 'Sunday', 'Thursday']  

Not covered words are at the end, in alphabetic order.

B. M.
  • 18,243
  • 2
  • 35
  • 54
0

I'm not sure how you get the order of the unsorted item in your list so I assume they are unsorted.

Here's an example:

        input_list = ['Saturday', 'Tuesday', 'Sunday', 'Monday', 'Thursday', 'Wednesday', 'Cheeseburger', 'Friday']
        list_sorter = ['Mon', 'Tue', 'Wed']
        list_sorter.reverse()
        tupple_list = []
        for element in input_list:
            sub_string = element[0:3]
            if sub_string in list_sorter:
                index = list_sorter.index(sub_string) + 1
            else:
                index = 0
            tupple_list.append((element, index))
        sorted_list = sorted(tupple_list, key=lambda x: x[1], reverse = True)
        output_list = []
        for tupple in sorted_list:
            output_list.append(tupple[0])
        print (output_list)

Giving:

['Monday', 'Tuesday', 'Wednesday', 'Saturday', 'Sunday', 'Thursday', 'Cheeseburger', 'Friday']
Steve
  • 476
  • 3
  • 10
0
from functools import partial

def keysort(value, lOrder):
    index = 10000
    for i, pmatch in enumerate(lOrder, 1):
        if value.upper().find(pmatch.upper())!=-1:
            index=i
            break
    return index

def main():
    list_sorter = ['Mon', 'Tue', 'rida']
    output_list = ['Thursday', 'Saturday', 'Tuesday', 'Friday', 'Cheeseburger', 'Monday', 'Sunday', 'Wednesday']
    slist = sorted(output_list, key=partial(keysort, lOrder=list_sorter))
    print (slist)
#['Monday', 'Tuesday', 'Friday', 'Thursday', 'Saturday', 'Cheeseburger', 'Sunday', 'Wednesday']
if __name__ == '__main__':
    main()