Budeme pokračovat v našem "telefonním seznamu". Každého jistě napadlo, co všechno náš program by mohl umět. Mě osobně tam chybí možnost uložení do souboru, abych měl data přístupná i po skončení programu. Někdo by rád v seznamu vyhledával a vypisoval výsledky. Vylepšovat můžeme prakticky vše. Dneska se podíváme na možnosti seřazení seznamu podle abecedy.
Telefonní seznam 2.
Budeme pokračovat v našem "telefonním seznamu". Každého jistě napadlo, co všechno náš program by mohl umět. Mě osobně tam chybí možnost uložení do souboru, abych měl data přístupná i po skončení programu. Abych je nemusel znovu a znovu zadávat. Někdo by to rád viděl v okně, jako klasickou okenní aplikaci. Někdo by rád v seznamu vyhledával a vypisoval výsledky. Vylepšovat můžeme prakticky vše. Dneska se podíváme na možnosti seřazení seznamu podle abecedy.Řazení
Přestavte si, že náš telefonní seznam chceme vytisknout dle abecedy. Seřadit obyčejný seznam podle abecedy nebo velikosti čísel není v Pythonu nic těžkého.
>>> mesta=['Praha','Brno','Ostrava','Zlin']
>>> pocetObyvatel=[1000000, 350000, 300000, 80000]
>>> print mesta.sort() # takto se nevytiskne nic, presto, ze se seznam seradi
None
Dejte pozor - metoda sort() nic nevrací (lépe řečeno 'nic' vrací). Nic znamená často v programování 'None' a právě proto to print vytiskne. Řadí takzvaně 'na místě' ('in place'). Správné syntaktické použití metody sort() je
>>> mesta.sort()
>>> pocetObyvatel.sort()
>>> print mesta, pocetObyvatel
['Brno', 'Ostrava', 'Praha', 'Zlin'] [80000, 300000, 350000, 1000000]
Syntakticky správně, logicky však špatně :-(. Na druhý pohled je vidět nedostatek tohoto postupu. Přestože na začátku seznamy samy sobě odpovídaly, seřadily se nezávisle na sobě a teď již neplatí, že např. Brno má 80000 obyvatel. Co s tím?
Seznamy v seznamech
Seznamy mohou obsahovat téměř vše: čísla, řetězce, ale i další, vnořené seznamy. Vyzkoušejte:
>>> x = [2, 'neco']
>>> y = [1, x, 4]
>>> print y
[1, [2, 'neco'], 4]
>>> print y[1]
[2, 'neco']
>>> y.append([5,'cosi'])
>>> print y, len(y)
[1, [2, 'neco'], 4, [5, 'cosi']] 4
>>> print x, len(x)
[2, 'neco'] 2
Mít seznam v seznamu je v našem případě velmi výhodné. Jednak nemusíme udržovat několik seznamů (jako v minulé lekci). Budeme mít tedy jeden , který bude obsahovat ve vnitřních seznamech vše co chceme a navíc získáme jednoduché řešení, když chceme seznamy řadit.
Řazení prosté
Chceme-li seznam seřadit podle první položky vnořeného seznamu, uděláme to jednoduše:
>>> mesta=[['Ostrava', 300000], ['Praha', 1000000], ['Brno', 350000], ['Zlin', 80000]]
>>> mesta.sort()
>>> print mesta
[['Brno', 350000], ['Ostrava', 300000], ['Praha', 1000000], ['Zlin', 80000]]
Jména a počty jsou takto nerozbitně spojeny a řadí se současně. Můžeme takto jednoduše do vnitřních seznamů přidat ještě cokoliv dalšího, např. region, počty škol,... a při řazení bude vše zůstávat ve správném spojení.
Řazení podle počtu obyvatel
Tato je úloha je poměrně složitější. K jejímu řešení existuje několik cest, od low-level, tedy ruční naprogramování, až po high-level, co nám za funkce všechno jazyk umožňuje. De facto potřebujeme řadit podle druhé položky (vlastně první, protože první je nultá). Na to má Python 2.4 argument "key" v metodě sort() a s pomocí dodatečné funkce to řeší takto:
def porovnej(mestoSeznam):
# definice funkce, která bude spolupracovat se sort()
return mestoSeznam[1] # zde vracíme tu položku, podle které chceme řadit
mesta=[['Praha', 1000000], ['Brno', 350000], ['Ostrava', 300000], ['Zlin', 80000]]
mesta.sort(key=porovnej) # serad podle klice (= funkce) "porovnej"
print "Serazeno podle poctu obyvatel: ", mesta
Procházení seznamem v seznamu
Jako obvykle, Python nabízí jednoduché přesto mocné řešení:
for mestoSeznam in mesta:
print mestoSeznam # tisk celého vnitřního seznamu
print mestoSeznam[0], mestoSeznam[1] #nebo přes jeho položky
Python však nabízí dokonce i jednu feature ;-), kterou mu mohou ostatní jazyky tiše závidět. Prosté procházení přímo přes položky vnitřního seznamu:
for mesto, pocet in mesta:
print mesto, pocet
Tak to by pro dnešek stačilo. Příště budeme ukládat do souboru. Několika způsoby.
Úkol
Zadání
Upravte váš dosavadní program tak, aby při zadávání se data ukládala do seznamu v seznamu a na konci vytiskněte seznam seřazený podle abecedy. Dále vypište, kolik je ve vašem seznamu lidí.
Extra pro pokročilé
Vytiskněte seznam navíc "obrácený", to znamená, že bude seřazen podle abecedy, ale odzadu, od "z" do "a". Budete k tomu asi potřebovat na Internetu vyhledat další parametr funkce sort().
Tip
Mrkněte na nové logo i barvy pythonýrského portálu.