ukotvit menu |
Python defaultně třídí řetězce podle velikosti ASCII kódů jednotlivých znaků. To jakž takž funguje pro angličtinu, ale nikoli pro češtinu. Naštěstí Python dobře podporuje linuxové locale a tak zařídit správné třídění není těžké. Viz. samostatný článek o locale.
Klíčové jsou dvě funkce setlocale() a strcoll() z modulu locale. Pomocí funkce setlocale() na 3. řádku nastavíme aplikaci správné locale. Funkci strcoll() na 11. radku předáme metodě seznamu sort(), která s její pomocí provede správné střídění podle nastaveného locale. To je všechno.
1 # encoding: utf-8 2 import locale 3 locale.setlocale(locale.LC_ALL,'cs_CZ.utf8') 4 5 seznam = ["žízeň", "zábava", "údy", "uzel", 6 "chlap", "čumil", "důkaz", "civil", 7 "řetěz", "rozum", "ábel", "atom", 8 "óda", "ovar", "adam", "Adam", 9 "Žaneta", "Čenda"] 10 11 seznam.sort(locale.strcoll) 12 for termin in seznam: 13 print termin
Tohle bohužel nebude fungovat ve Windows (Microsoft buď proklet), protože mají locale pouze pro cp1250. Řešením by mohl být používat toto kódování, ale s tím narazíte u GUI knihoven, které používají univerzální utf-8. S tím souvisí i další problém Windows, protože ty na konzoli používají jiné kódování a to cp852.
Řešením je převést řetězce se kterými pracujete na Unicode, pracovat s nimi v této formě a před vypsáním je překódovat na kódování, které potřebujete, třeba utf-8 pro GUI nebo cp852 pro konzoli. Příklad pro Windows s výstupem na českou konzoli:
1 # encoding: utf-8 2 import locale 3 4 # nastaveni systemového locale 5 locale.setlocale(locale.LC_ALL,'') 6 7 # data k setrideni 8 seznam = ["žízeň", "zábava", "údy", "uzel", 9 "chlap", "čumil", "důkaz", "civil", 10 "řetěz", "rozum", "ábel", "atom", 11 "óda", "ovar", "adam", "Adam", 12 "Žaneta", "Čenda"] 13 14 # prekodovani na Unicode 15 uSeznam = [] 16 for termin in seznam: 17 uSeznam.append(termin.decode('utf-8')) 18 19 # trideni 20 uSeznam.sort(locale.strcoll) 21 22 # vypis na konzoli 23 for termin in uSeznam: 24 print termin.encode('cp852') 25 26 # -------------- to je vsechno -------------- 27 28 # ALTERNATIVNI ZPUSOBY PREKODOVANI NA UNICODE 29 30 # bez pouziti noveho seznamu: 31 for i, termin in enumerate(seznam): 32 seznam[i] = termin.decode('utf-8') 33 34 # s novym seznamem, ale na jeden radek: 35 uSeznam = [t.decode('utf-8') for t in seznam]
Výsledek třídění je tento:
ábel adam Adam atom civil Čenda čumil důkaz chlap óda ovar rozum řetěz údy uzel zábava Žaneta žízeň