Sprachabhängige Sortierung
Verfasst: Dienstag 13. August 2013, 09:37
Guten Tag.
Ich möchte je nach eingestelltem Locale eine sprachabhängige Sortierung haben. Mir ist klar, dass alles was mit Locales zu tun hat, ein heikles Thema ist - zumindest wenn man dafür die globale Einstellung von Python kurz ändern muss.
Eine Sortierung ohne umgestelltem Locale sähe ja so aus:
Er behält also quasi die Reihenfolge bei. Ich hätte aber gerne das "bämm" hinter dem "bamm".
Meine erste Idee war, das `locale`-Modul zu benutzen. Um den Code noch halbwegs aufzuhübschen hatte ich mir dann sowas gebastelt:
Das sieht erstmal (den Umständen entsprechend) gut aus, aber scheint für Unicode-Strings kaputt zu sein:
Gibt es eine Möglichkeit, das beschriebene Ziel mit vertretbarem Aufwand auch für Unicode-Strings zu erreichen oder müsste ich in diesem Fall definitv auf PyICU ausweichen (siehe: http://stackoverflow.com/a/3413436)?
EDIT: Schon wohl nur Python 2.x zu betreffen. Python 3.x nutzt intern `wcsxfrm()` und kommt dementsprechend mit Unicode klar. Zwar sind dort Bytes verboten, aber das ist ja noch einigermaßen ok. Ich überlege, ob ich einfach `wcsxfrm()` mit `ctypes` wrappe, um die Abhängigkeit zu PyICU maximal optional zu machen. Werde berichten...
Ich möchte je nach eingestelltem Locale eine sprachabhängige Sortierung haben. Mir ist klar, dass alles was mit Locales zu tun hat, ein heikles Thema ist - zumindest wenn man dafür die globale Einstellung von Python kurz ändern muss.
Eine Sortierung ohne umgestelltem Locale sähe ja so aus:
Code: Alles auswählen
>>> items = ['bamm', 'bumm', 'bämm']
>>> print ' '.join(sorted(items))
bamm bumm bämmMeine erste Idee war, das `locale`-Modul zu benutzen. Um den Code noch halbwegs aufzuhübschen hatte ich mir dann sowas gebastelt:
Code: Alles auswählen
In [1]: import locale
In [2]: %paste
class _DefaultLocale(object):
def __init__(self, category):
self.category = category
self.old_locale = locale.getlocale(category)
self.default_locale = locale.getdefaultlocale()
def __enter__(self):
locale.setlocale(self.category, self.default_locale)
def __exit__(self, *unused):
locale.setlocale(self.category, self.old_locale)
## -- End pasted text --
In [3]: items = ['bamm', 'bumm', 'bämm']
In [4]: with _DefaultLocale(locale.LC_COLLATE):
...: print ' '.join(sorted(items, key=locale.strxfrm))
...:
bamm bämm bummCode: Alles auswählen
In [5]: items = [u'bamm', u'bumm', u'bämm']
In [6]: with _DefaultLocale(locale.LC_COLLATE):
print ' '.join(sorted(items, key=locale.strxfrm))
...:
---------------------------------------------------------------------------
UnicodeEncodeError Traceback (most recent call last)
<ipython-input-6-bb4ce974ad48> in <module>()
1 with _DefaultLocale(locale.LC_COLLATE):
----> 2 print ' '.join(sorted(items, key=locale.strxfrm))
3
UnicodeEncodeError: 'ascii' codec can't encode character u'\xe4' in position 1: ordinal not in range(128)EDIT: Schon wohl nur Python 2.x zu betreffen. Python 3.x nutzt intern `wcsxfrm()` und kommt dementsprechend mit Unicode klar. Zwar sind dort Bytes verboten, aber das ist ja noch einigermaßen ok. Ich überlege, ob ich einfach `wcsxfrm()` mit `ctypes` wrappe, um die Abhängigkeit zu PyICU maximal optional zu machen. Werde berichten...