W poprzedniej części nauczyłeś się jak proste jest łączenie elementów listy w string. Naszym ostatecznym celem jest analiza tekstu, czyli naszymi danymi wejściowymi jest tekst i to tekst na pewnym etapie będziemy przekształcać na listę. W tej części nauczysz się jak string (czyli tekst) podzielić i zamienić na listę.
Do takiej zmiany użyjesz na stringu metody .split(). Zasadę działania możesz przetestować bezpośrednio w terminalu IDLE:
>>> "Zasadę działania możesz przetestować bezpośrednio w terminalu IDLE:".split()
['Zasadę', 'działania', 'możesz', 'przetestować', 'bezpośrednio', 'w', 'terminalu', 'IDLE:']
>>>
Metoda .split() tworzy listę, gdzie domyślnym znakiem oddzielającym kolejne elementy listy jest spacja. Nic nie stoi na przeszkodzie, żeby spację zastąpić innym znakiem, podając go jako argument. Zauważ, że .split("e") nie jest równoważne .split("E"):
>>> "Zasadę działania możesz przetestować bezpośrednio w terminalu IDLE:".split("e")
['Zasadę działania moż', 'sz prz', 't', 'stować b', 'zpośr', 'dnio w t', 'rminalu IDLE:']
>>> "Zasadę działania możesz przetestować bezpośrednio w terminalu IDLE:".split("E")
['Zasadę działania możesz przetestować bezpośrednio w terminalu IDL', ':']
>>>
Metoda .split() może nam posłużyć do sprawdzenia ile razy w stringu występuje dany wyraz albo słowo. Napiszmy program, który powie nam ile razy występuje słowo Bóg w pierwszym rozdziale Księgi Rodzaju (nie przepisuj całego rozdziału, można go skopiować np. stąd nie przejmuj się formatowaniem tekstu, po prostu wklej go miedzy " a " i pozbądź się enterów. Możesz to zrobić używając https://codebeautify.org/text-minifier, wklej tekst w górne okienko, odznacz opcję „Remove space”, zaznacz opcje „Remove line”, kliknij „Minify”, skopiuj zawartość dolnego okienka i wklej. Potrzebujesz baaardzo długiej linijki tekstu możesz też skopiować tekst z poniższego przykładu.
rozdzial = "1 Na początku Bóg stworzył niebo i ziemię.\
2 Ziemia zaś była bezładem i pustkowiem: ciemność była nad powierzchnią\
bezmiaru wód, a Duch2 Boży unosił się nad wodami.\
3 Wtedy Bóg rzekł: «Niechaj się stanie światłość!» I stała się światłość.\
4 Bóg widząc, że światłość jest dobra, oddzielił ją od ciemności. \
5 I nazwał Bóg światłość dniem, a ciemność nazwał nocą.\
I tak upłynął wieczór i poranek - dzień pierwszy.\
6 A potem Bóg rzekł: «Niechaj powstanie sklepienie w środku wód i niechaj \
ono oddzieli jedne wody od drugich!» \
7 Uczyniwszy to sklepienie, Bóg oddzielił wody pod sklepieniem od wód \
ponad sklepieniem; a gdy tak się stało, \
8 Bóg nazwał to sklepienie niebem.\
I tak upłynął wieczór i poranek - dzień drugi.\
9 A potem Bóg rzekł: «Niechaj zbiorą się wody spod nieba w jedno miejsce\
i niech się ukaże powierzchnia sucha!» A gdy tak się stało, \
10 Bóg nazwał tę suchą powierzchnię ziemią, a zbiorowisko wód nazwał \
morzem. Bóg widząc, że były dobre, \
11 rzekł: «Niechaj ziemia wyda rośliny zielone: trawy dające nasiona, \
drzewa owocowe rodzące na ziemi według swego gatunku owoce, w których są \
nasiona». I stało się tak. \
12 Ziemia wydała rośliny zielone: trawę dającą nasienie według swego \
gatunku i drzewa rodzące owoce, w których było nasienie według ich \
gatunków. A Bóg widział, że były dobre.\
13 I tak upłynął wieczór i poranek - dzień trzeci.\
14 A potem Bóg rzekł: «Niechaj powstaną ciała niebieskie, świecące na \
sklepieniu nieba, aby oddzielały dzień od nocy, aby wyznaczały pory roku, \
dni i lata; \
15 aby były ciałami jaśniejącymi na sklepieniu nieba i aby świeciły nad \
ziemią». I stało się tak. \
16 Bóg uczynił dwa duże ciała jaśniejące: większe, aby rządziło dniem, \
i mniejsze, aby rządziło nocą, oraz gwiazdy. \
17 I umieścił je Bóg na \
sklepieniu nieba, aby świeciły nad ziemią; \
18 aby rządziły dniem i nocą i oddzielały światłość od ciemności. A \
widział Bóg, że były dobre.\
19 I tak upłynął wieczór i poranek - dzień czwarty.\
20 Potem Bóg rzekł: «Niechaj się zaroją wody od roju istot żywych, a \
ptactwo niechaj lata nad ziemią, pod sklepieniem nieba!» \
21 Tak stworzył Bóg wielkie potwory morskie i wszelkiego rodzaju pływające \
istoty żywe, którymi zaroiły się wody, oraz wszelkie ptactwo skrzydlate \
różnego rodzaju. Bóg widząc, że były dobre, \
22 pobłogosławił je tymi słowami: «Bądźcie płodne i mnóżcie się, \
abyście zapełniały wody morskie, a ptactwo niechaj się rozmnaża na \
ziemi».\
23 I tak upłynął wieczór i poranek - dzień piąty.\
24 Potem Bóg rzekł: «Niechaj ziemia wyda istoty żywe różnego rodzaju: \
bydło, zwierzęta pełzające i dzikie zwierzęta według ich rodzajów!» I \
stało się tak. \
25 Bóg uczynił różne rodzaje dzikich zwierząt, bydła i wszelkich \
zwierząt pełzających po ziemi. I widział Bóg, że były dobre. \
26 A wreszcie rzekł Bóg: «Uczyńmy człowieka na Nasz obraz, podobnego \
Nam. Niech panuje nad rybami morskimi, nad ptactwem powietrznym, nad \
bydłem, nad ziemią i nad wszystkimi zwierzętami pełzającymi po ziemi!»\
27 Stworzył więc Bóg człowieka na swój obraz,\
na obraz Boży go stworzył:\
stworzył mężczyznę i niewiastę.\
28 Po czym Bóg im błogosławił, mówiąc do nich: «Bądźcie płodni i \
rozmnażajcie się, abyście zaludnili ziemię i uczynili ją sobie poddaną; \
abyście panowali nad rybami morskimi, nad ptactwem powietrznym i nad \
wszystkimi zwierzętami pełzającymi po ziemi». \
29 I rzekł Bóg: «Oto wam daję wszelką roślinę przynoszącą ziarno po \
całej ziemi i wszelkie drzewo, którego owoc ma w sobie nasienie: dla \
was będą one pokarmem. \
30 A dla wszelkiego zwierzęcia polnego i dlawszelkiego ptactwa w \
powietrzu, i dla wszystkiego, co się porusza po ziemi i ma w sobie \
pierwiastek życia, będzie pokarmem wszelka trawa zielona». I stało się \
tak. \
31 A Bóg widział, że wszystko, co uczynił, było bardzo dobre.I tak \
upłynął wieczór i poranek - dzień szósty."
liczba_wyrazów = rozdzial.split("Bóg")
print(len(liczba_wyrazów))
W powyższym programie:
- W 1 linijce pod zmienną
rozdzialpodstawiasz bardzo długi string zawierający cały pierwszy rozdział Księgi Rodzaju. - Następnie, w 71 linijce, pod zmienną
liczba_wyrazowpodstawiasz listę, której elementami są stringi zmiennejrozdzialpodzielone słowem Bóg. - Na koniec, w 72 linijce, funkcja
print()drukuje długość listyliczba_wyrazow.
W powyższym kodzie pojawił się backslash „\” bez żadnego dodatkowego znaku, czemu on służy? Zdarzy ci się nie raz, że twój kod będzie zawierał długą linijkę. Np. coś takiego:
lista_wyrazow = "W powyższym kodzie pojawił się znów backslash \\ bez żadnego dodatkowego znaku, czemu on służy? Zdarzy ci się nie raz, że twój kod będzie zawierał długą linijkę. Np. coś takiego".split()
Żeby dowiedzieć się, co w tej linijce kodu się stało (zmienna lista_wyrazow to lista składająca się z elementów stringa rozdzielonych spacjami), musisz przewinąć ekran daleko w prawo. Stosując w kodzie \ i wciskając enter informujesz Pythona, że nie chcesz zaczynań nowej linii kodu, a chcesz kontynuować poprzednią linię. Taki zabieg poprawia czytelność:
lista_wyrazow = "W powyższym kodzie pojawił się znów backslash \\ \
bez żadnego dodatkowego znaku, czemu on służy? Zdarzy ci się nie \
raz, że twój kod będzie zawierał długą linijkę. Np. coś takiego".split()
Wracamy do napisanego programu. Uruchom program i sprawdź działanie:
======================== RESTART: F:/python38/wpis 5.py ========================
27
>>>
Teraz wiemy, że po podziale mamy listę składającą się z 27 elementów. Czyli wiemy, że słowo „Bóg” występuje 26 razy w pierwszym rozdziale Księgi Rodzaju (gdyby występowało 1 raz lista miałaby 2 elementy. Gdyby słowo występowało 3 razy lista miałaby 4 elementy). Uładnijmy nieco ostatni print(). Chcemy, żeby nasz pogram wydrukował „W tekście wyraz „Bóg” występuje 26 razy”. Łączenie stringów jest w Pythonie bardzo proste, zrobimy to bezpośrednio w funkcji print(). Zacznijmy od prostego przykładu:
print("W tekście wyraz " + "WyrazWCudzysłowie " + \
"występuje " + "LiczbaWystąpień " + "razy")
Po uruchomieniu otrzymasz:
======================== RESTART: F:/python38/wpis 5.py ========================
W tekście wyraz WyrazWCudzysłowie występuje LiczbaWystąpień razy
>>>
Jak dotąd wszystko w porządku, znak „+” tak jak można się było domyślić dodaje do siebie stringi! Zmieńmy nieco wynik, dodajmy słowo Bóg w cudzysłowach (pamiętaj o użyciu backslashy w wymaganych miejscach):
print("W tekście wyraz \"Bóg\" występuje " + "LiczbaWystąpień " + "razy")
Efekt:
======================== RESTART: F:/python38/wpis 5.py ========================
W tekście wyraz "Bóg" występuje LiczbaWystąpień razy
Dodajmy ostatni element, czyli len(liczba_wyrazow)
print("W tekście wyraz \"Bóg\" występuje " + len(liczba_wyrazow) + "razy")
Efekt:
======================== RESTART: F:/python38/wpis 5.py ========================
Traceback (most recent call last):
File "F:/python38/wpis 5.py", line 79, in <module>
print("W tekście wyraz \"Bóg\" występuje " + len(liczba_wyrazow) + "razy")
TypeError: can only concatenate str (not "int") to str
>>>
Błąd! Coś nie wyszło. Na szczęście Python stara się powiedzieć, co poszło nie tak: "TypeError: can only concatenate str (not "int") to str". TypeError informuje o nieprawidłowym typie danych. Łączenie stringów to operacja, w której udział mogą brać tylko stringi. len(liczba_wyrazow) jest liczbą (int). Na szczęście w Pythonie łatwo zamienić int na str za pomocą funkcji str():
>>> 27
27
>>> str(27)
'27'
>>>
Napiszmy poprawioną wersję print() w programie. Musimy jako argument funkcji str() umieścić funkcję len(), której argumentem jest zmienna liczba_wyrazow:
print("W tekście wyraz \"Bóg\" występuje " + str(len(liczba_wyrazow)) + " razy")
Uruchom program i sprawdź efekt:
======================== RESTART: F:/python38/wpis 5.py ========================
W tekście wyraz "Bóg" występuje 27 razy
>>>
Jeszcze jedno nam zostało, trzeba odjąć od długości listy 1 (Jeden wyraz Bóg, dzieli tekst na dwie części, dwa wyrazy Bóg na trzy części itd). W Pythonie odejmowanie liczb nie różni się niczym od używania kalkulatora, czy Excela. Pamiętaj, żeby odjąć zanim program zamieni liczbę na string, python nie potrafi odejmować i dodawać liczb do stringów, zobaczmy cały program:
rozdzial = "1 Na początku Bóg stworzył niebo i ziemię.\
2 Ziemia zaś była bezładem i pustkowiem: ciemność była nad powierzchnią\
bezmiaru wód, a Duch2 Boży unosił się nad wodami.\
3 Wtedy Bóg rzekł: «Niechaj się stanie światłość!» I stała się światłość.\
4 Bóg widząc, że światłość jest dobra, oddzielił ją od ciemności. \
5 I nazwał Bóg światłość dniem, a ciemność nazwał nocą.\
I tak upłynął wieczór i poranek - dzień pierwszy.\
6 A potem Bóg rzekł: «Niechaj powstanie sklepienie w środku wód i niechaj \
ono oddzieli jedne wody od drugich!» \
7 Uczyniwszy to sklepienie, Bóg oddzielił wody pod sklepieniem od wód \
ponad sklepieniem; a gdy tak się stało, \
8 Bóg nazwał to sklepienie niebem.\
I tak upłynął wieczór i poranek - dzień drugi.\
9 A potem Bóg rzekł: «Niechaj zbiorą się wody spod nieba w jedno miejsce\
i niech się ukaże powierzchnia sucha!» A gdy tak się stało, \
10 Bóg nazwał tę suchą powierzchnię ziemią, a zbiorowisko wód nazwał \
morzem. Bóg widząc, że były dobre, \
11 rzekł: «Niechaj ziemia wyda rośliny zielone: trawy dające nasiona, \
drzewa owocowe rodzące na ziemi według swego gatunku owoce, w których są \
nasiona». I stało się tak. \
12 Ziemia wydała rośliny zielone: trawę dającą nasienie według swego \
gatunku i drzewa rodzące owoce, w których było nasienie według ich \
gatunków. A Bóg widział, że były dobre.\
13 I tak upłynął wieczór i poranek - dzień trzeci.\
14 A potem Bóg rzekł: «Niechaj powstaną ciała niebieskie, świecące na \
sklepieniu nieba, aby oddzielały dzień od nocy, aby wyznaczały pory roku, \
dni i lata; \
15 aby były ciałami jaśniejącymi na sklepieniu nieba i aby świeciły nad \
ziemią». I stało się tak. \
16 Bóg uczynił dwa duże ciała jaśniejące: większe, aby rządziło dniem, \
i mniejsze, aby rządziło nocą, oraz gwiazdy. \
17 I umieścił je Bóg na \
sklepieniu nieba, aby świeciły nad ziemią; \
18 aby rządziły dniem i nocą i oddzielały światłość od ciemności. A \
widział Bóg, że były dobre.\
19 I tak upłynął wieczór i poranek - dzień czwarty.\
20 Potem Bóg rzekł: «Niechaj się zaroją wody od roju istot żywych, a \
ptactwo niechaj lata nad ziemią, pod sklepieniem nieba!» \
21 Tak stworzył Bóg wielkie potwory morskie i wszelkiego rodzaju pływające \
istoty żywe, którymi zaroiły się wody, oraz wszelkie ptactwo skrzydlate \
różnego rodzaju. Bóg widząc, że były dobre, \
22 pobłogosławił je tymi słowami: «Bądźcie płodne i mnóżcie się, \
abyście zapełniały wody morskie, a ptactwo niechaj się rozmnaża na \
ziemi».\
23 I tak upłynął wieczór i poranek - dzień piąty.\
24 Potem Bóg rzekł: «Niechaj ziemia wyda istoty żywe różnego rodzaju: \
bydło, zwierzęta pełzające i dzikie zwierzęta według ich rodzajów!» I \
stało się tak. \
25 Bóg uczynił różne rodzaje dzikich zwierząt, bydła i wszelkich \
zwierząt pełzających po ziemi. I widział Bóg, że były dobre. \
26 A wreszcie rzekł Bóg: «Uczyńmy człowieka na Nasz obraz, podobnego \
Nam. Niech panuje nad rybami morskimi, nad ptactwem powietrznym, nad \
bydłem, nad ziemią i nad wszystkimi zwierzętami pełzającymi po ziemi!»\
27 Stworzył więc Bóg człowieka na swój obraz,\
na obraz Boży go stworzył:\
stworzył mężczyznę i niewiastę.\
28 Po czym Bóg im błogosławił, mówiąc do nich: «Bądźcie płodni i \
rozmnażajcie się, abyście zaludnili ziemię i uczynili ją sobie poddaną; \
abyście panowali nad rybami morskimi, nad ptactwem powietrznym i nad \
wszystkimi zwierzętami pełzającymi po ziemi». \
29 I rzekł Bóg: «Oto wam daję wszelką roślinę przynoszącą ziarno po \
całej ziemi i wszelkie drzewo, którego owoc ma w sobie nasienie: dla \
was będą one pokarmem. \
30 A dla wszelkiego zwierzęcia polnego i dlawszelkiego ptactwa w \
powietrzu, i dla wszystkiego, co się porusza po ziemi i ma w sobie \
pierwiastek życia, będzie pokarmem wszelka trawa zielona». I stało się \
tak. \
31 A Bóg widział, że wszystko, co uczynił, było bardzo dobre.I tak \
upłynął wieczór i poranek - dzień szósty."
liczba_wyrazow = rozdzial.split("Bóg")
print("W tekście wyraz \"Bóg\" występuje " + str(len(liczba_wyrazow) - 1) + " razy")
Uruchom program i sprawdź efekt:
======================== RESTART: F:\python38\wpis 5.py ========================
W tekście wyraz "Bóg" występuje 26 razy
>>>
Takie łączenie stringów jest jak najbardziej prawidłowe, ale nie najlepsze. W Pythonie zaleca się używanie f-string. Dzięki f-string nie będziesz musiał używać + ani dużej ilości cudzysłowów. Do użycia f-string musisz zrobić dwie rzeczy.
- Poinformować Pythona, że chcesz użyć f-string poprzez dodanie f przed stringiem:
f"" - wszytko co nie jest stringiem, np. zmienna czy funkcja musisz umieścić w wąsatych nawiasach
{}
Poprawmy print() według tej instrukcji:
print(f"W tekście wyraz \"Bóg\" występuje {str(len(liczba_wyrazow) - 1)} razy")
Prawda, że teraz print() wygląda dużo czytelniej? Zobaczmy efekt raz jeszcze:
======================== RESTART: F:\python38\wpis 5.py ========================
W tekście wyraz "Bóg" występuje 26 razy
>>>
Teraz pod zmienną rozdział możesz podstawić, np. drugi rozdział Księgi Rodzaju i twój program policzy, jak często w nim występuje słowo Bóg.
Podsumowanie
Świetnie ci idzie! Nauczyłeś się właśnie, jak podzielić dowolny tekst i zrobić z niego listę, jak przygotować długi tekst do podania go Pythonowi w zrozumiałej formie, i jak napisać program, który, dzięki twoim umiejętnościom, przeanalizuje liczbę wystąpień litery, liter, wyrazów.
Zadanie domowe
Podążanie za instrukcjami, nawet jeśli je wszystkie wykonujesz samodzielnie, nie zrobi z ciebie programisty. Zadania domowe mogą wydawać się na początku trudne. Tu nie ma rozwiązania podanego na talerzu, użyj dowolnych źródeł, by znaleźć odpowiedź.
- Przygotowanie długiego stringa jest mocno kłopotliwe. Zauważ, że musiałeś usuwać entery, by pozbyć się nowej linii. Po drugie jeśli string umieścisz między ” ” to jeśli w tekście pojawi się ” musisz go oznaczyć backslashem \”. Jeśli umieścisz string między ’ ’ to jeśli w tekście pojawi się ’ musisz go oznaczyć backslashem \’. Python pozwala wkleić string składający się z wielu linijek tekstu bez potrzeby usuwania enterów i praktycznie nie musisz się martwić o różnego rodzaju cudzysłowy. Znajdź ten sposób, przetestuj na dowolnym, długim tekście.
- Przygotuj string składający się z kilu słów zawierających „rz” np. „rzeka rzeźba krzak”. Używając funkcji
split()i.join()zamień „rz” na „ż”. Ostatecznym efektem ma być string.