Home > Back-end >  Sort list after specific order from another list
Sort list after specific order from another list

Time:12-28

I have three lists:

weekdays = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday']
selected_weekdays = ['Friday', 'Monday', 'Thursday']
selected_weekdays_unix = ['8276583', '3724252', '2324626']

My goal is to sort the selected_weekdays and selected_weekdays_unix lists after weekdays. Meaning, the code would return:

['Monday', 'Thursday', 'Friday']
['3724252', '2324626', '8276583']

Note that the positions of the items in the selected_weekdays correlate with the position of the items in the selected_weekdays_unix. So, 'Monday', would correlate to '3724252'. 'Friday' would correlate to '8276583' and so on.

I managed to sort the selected_weekdays by using the sorted() function. Like this:

sorted_selected_weekdays = sorted(selected_weekdays, key=weekdays.index)

Here's the problem. Now, I want to sort the selected_weekdays_unix after how the selected_weekdays list was sorted. Remember that I said that the items position correlate with each other. Now that the selected_weekdays is sorted, I want to sort the selected_weekdays_unix to the same positions, so that the output would be:

['3724252', '2324626', '8276583']

I tried doing it like this:

sorted_selected_weekdays_unix = sorted(selected_weekdays_unix, key=sorted_selected_weekdays.index)

It didn't work as the values didn't match, and the truth is that I have no clue how I can sort the list in an efficient way.

Do you have any ideas?

CodePudding user response:

I would zip the two "selected" lists together.

>>> s = list(zip(selected_weekdays, selected_weekdays_unix))
>>> s
[('Friday', '8276583'), ('Monday', '3724252'), ('Thursday', '2324626')]

And then sort by the index of the first element in the weekdays list.

>>> s = sorted(s, key=lambda x: weekdays.index(x[0]))
>>> s
[('Monday', '3724252'), ('Thursday', '2324626'), ('Friday', '8276583')]

Now you just have to separate out the pieces you want:

>>> a, b = [x[0] for x in s], [x[1] for x in s]
>>> a
['Monday', 'Thursday', 'Friday']
>>> b
['3724252', '2324626', '8276583']

Or employ zip again:

>>> a, b = list(zip(*s))
>>> a
('Monday', 'Thursday', 'Friday')
>>> b
('3724252', '2324626', '8276583')

CodePudding user response:

Here's one way:

# Create an index of the sorted weekdays to avoid having to walk
# the weekdays list multiple times.
weekdays_index = {d:i for i, d in enumerate(weekdays)}

# Combine and sort the two input lists
combined = sorted(zip(selected_weekdays, selected_weekdays_unix), key=lambda k: weekdays_index[k[0]])

# extract the two desired outputs
print([c[0] for c in combined])
print([c[1] for c in combined])

Result:

['Monday', 'Thursday', 'Friday']
['3724252', '2324626', '8276583']

CodePudding user response:

Instead of sorting them separately, sort them both at the same time:

sorted_lists = sorted(
    zip(selected_weekdays, selected_weekdays_unix), 
    key=lambda x: weekdays.index(x[0])
)

Then split them into two separate lists again:

selected_weekdays, selected_weekdays_unix = [list(s) for s in zip(*sorted_lists)]

selected_weekdays, selected_weekdays_unix
>>> (['Monday', 'Thursday', 'Friday'], ['3724252', '2324626', '8276583'])

CodePudding user response:

You can use the map function to map the indices of the elements in selected_weekdays to the elements in selected_weekdays_unix, and then use the sorted function to sort the mapped list.

# Sort selected_weekdays and selected_weekdays_unix using the indices of the elements in weekdays

sorted_weekdays = sorted(selected_weekdays, key=lambda x: weekdays.index(x))

sorted_weekdays_unix = list(map(lambda x: selected_weekdays_unix[selected_weekdays.index(x)], sorted_weekdays))

CodePudding user response:

Lookup table, zipping, and a list comprehension:

days = {day: i for i, day in enumerate(['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday'])}
selected_weekdays = ['Friday', 'Monday', 'Thursday']
selected_weekdays_unix = ['8276583', '3724252', '2324626']
sorted_weekdays, sorted_weekdays_unix = zip(*sorted(zip(selected_weekdays, selected_weekdays_unix), key=lambda pair: days[pair[0]]))
print(sorted_weekdays)
print(sorted_weekdays_unix)

Output:

('Monday', 'Thursday', 'Friday')
('3724252', '2324626', '8276583')

And I believe you might need to convert this to a list.

CodePudding user response:

Your code

weekdays = ['Monday', 'Tuesday', 'Wednesday', 'Thursday', 'Friday', 'Saturday', 'Sunday']
selected_weekdays = ['Friday', 'Monday', 'Thursday']
selected_weekdays_unix = ['8276583', '3724252', '2324626']
sorted_selected_weekdays = sorted(selected_weekdays, key=weekdays.index)

My addition

selected_weekdays_dict = {key: value for key, value in zip(selected_weekdays, selected_weekdays_unix)}
sorted_selected_weekdays_unix = list(map(lambda day: selected_weekdays_dict[day], sorted_selected_weekdays))

print(sorted_selected_weekdays)
print(sorted_selected_weekdays_unix)

Output

['Monday', 'Thursday', 'Friday']
['3724252', '2324626', '8276583']

CodePudding user response:

You can use zip in combination with a small function to generate the key to the sort function.

def sorter(weekdays):
    def get_index(tup):
        return weekdays.index(tup[0])
    return get_index

sorted_selected_weekdays, sorted_selected_weekdays_unix = zip(*sorted(zip(selected_weekdays, selected_weekdays_unix), key=sorter(weekdays)))
  • Related