přihlásit 3649/556454

České třídění

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ň

Parse error: syntax error, unexpected T_STRING in /web/htdocs2/wraithcz/home/www/python/data/sessions/sessions1.php on line 2