Search code examples
pythonlistsortingsetpriority-queue

Sort list by priority


How I can define a function priority_sort() that return a sorted list with its items in ascending order but prioritize the elements in the set over the other items in the list.

If the list is empty, return an empty list. If the set is empty there is nothing to prioritize, but the list should still be sorted. The set may contain values that are not in the list. The list may contain duplicates. The list and the set will only contain integer values.

Example

priority_sort([], {2, 3}) == []
priority_sort([], {}) == []
priority_sort([1, 2, 3], {}) == [1, 2, 3]
priority_sort([5, 4, 3, 2, 1], {3, 6}) == [3, 1, 2, 4, 5]
priority_sort([1, 5, 5, 5, 5, 2, 1], {1, 5}) == [1, 1, 5, 5, 5, 5, 2]
priority_sort([-5, -4, -3, -2, -1, 0], {-4, -3}) == [-4, -3, -5, -2, -1, 0]

My code

def priority_sort(unsort_lst, pri_set):
pri_set1 = list(pri_set)
new_list = sorted([i for i in unsort_lst if not i in pri_set1])
if unsort_lst == []:
    return []

for i in pri_set1:
    if i not in unsort_lst:
        pri_set1.remove(i)
return pri_set1 + new_list

But the test priority_sort([1, 5, 5, 5, 5, 2, 1], {1, 5}) == [1, 1, 5, 5, 5, 5, 2] return False


Solution

  • You can just make two lists, sort them separately, and concatenate:

    >>> xs = [-5, -4, -3, -2, -1, 0]
    >>> S = {-4, -3}
    >>> in_S = [x for x in xs if x in S]
    >>> not_in_S = [x for x in xs if not x in S]
    >>> list(sorted(in_S)) + list(sorted(not_in_S))
    [-4, -3, -5, -2, -1, 0]
    

    Alternately you can define a custom comparison function which maps each value to a tuple where the first element is a boolean representing whether the value is in the set, and the second element is the value itself:

    >>> list(sorted(xs, key=lambda x: (not x in S, x)))
    [-4, -3, -5, -2, -1, 0]