Reputation: 73
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.
Upvotes: 5
Views: 4128
Reputation: 11177
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']
Upvotes: 10