Arthur Martens Arthur Martens - 6 months ago 9
Python Question

How to sort a list of strings with a different order?

I am writing a function in python which can sort my list. The problem is that I don't want it in the same order that the

sorted()
method used. I tried using the
sorting()
method, but when I sort this string, which I it comes out like this:

0123456789abcdefghijklmnopqrstuvwxyzßàáäåæçèéêìíîñòóôöøùúüžα


The order I want it to be in is

0123456789aàáäåæbcçdeèéêfghiìíîjklmnñoòóôöøpqrsßtuùúüvwxyzžα


Now, I've got a list like this (example):

list = ['x', 'h', 'ê', 'ø', '5', 'ž', 'z', 'α', '3', '1']


And I want so sort it. If i'd use the
sorted()
method, it would look like this:

['1', '3', '5', 'h', 'x', 'z', 'ê', 'ø', 'ž', 'α']


But I want it to be in the same order as the string I gave before.

Does anyone know how to do this?

Answer

The idea is to associate to each char the index in the specified order and use the indexes of the string chars to do the order comparison.

Note: only works with Python 3

Sort one char strings

ORDER = "0123456789aàáäåæbcçdeèéêfghiìíîjklmnñoòóôöøpqrsßtuùúüvwxyzžα"
# associate each char with the index in the string
# this makes sort faster for multiple invocations when compared with
# ORDER.index(c)
POS = {c:p for (p, c) in enumerate(ORDER)}

lst = ['x', 'h', 'ê', 'ø', '5', 'ž', 'z', 'α', '3', '1']

lst.sort(key = lambda c: POS[c])
# or, suggested by wim
lst.sort(key = POS.get)

Sort any length strings

class MyStrOrder:
    def __init__(self, inner):
        self.inner = inner

    def __lt__(self, other):
        for i in range(min(len(self.inner), len(other.inner))):
            a = POS.get(self.inner[i])
            b = POS.get(other.inner[i])
            if a != b:
                return a < b
        return len(self.inner) < len(other.inner)

lst = ["abc", "ab", "aá"]
lst.sort()
print(lst)

lst = ["abc", "ab", "aá"]
lst.sort(key = MyStrOrder)
print(lst)

Outputs:

['ab', 'abc', 'aá']
['aá', 'ab', 'abc']
Comments