PPy3/SekwencjeIIteracja: Różnice pomiędzy wersjami
Linia 81: | Linia 81: | ||
</small></blockquote> | </small></blockquote> | ||
+ | Pętlę <tt>for</tt> można zatem zastosować do napisu - zamiast do listy, wówczas w kolejnych iteracjach będą uwzględniane kolejne znaki, a których składa się napis. | ||
+ | |||
+ | ===Ogólna postać pętli <tt>for</tt>=== | ||
+ | |||
+ | <source lang=python> | ||
+ | for element in sekwencja: | ||
+ | <blok instrukcji> | ||
+ | else: | ||
+ | <blok instrukcji> | ||
+ | </source> | ||
+ | |||
+ | *Pierwszy blok instrukcji będzie wykonany tyle razy, ile elementów ma sekwencja | ||
+ | *Za każdym razem nazwa ''element'' oznaczać będzie kolejny element sekwencji, zgodnie z ich porządkiem | ||
+ | *''sekwencja'' może być pusta; nie jest to błąd, ale wtedy pierwszy blok nie będzie wykonany ani razu | ||
+ | *Gdy elementy sekwencji się wyczerpią, wykonany zostanie blok po <tt>else</tt> | ||
+ | *Blok <tt>else</tt> (wraz z linijką go otwierającą) jest opcjonalny (niekonieczny) | ||
+ | *W pierwszym bloku mogą wystąpić specjalne polecenia: <tt>break</tt> i <tt>continue</tt> | ||
+ | **<tt>break</tt> znaczy: przerwij pętlę natychmiast, pomiń wszystkie pozostałe elementy sekwekcji, pomiń również ewentualny blok <tt>else</tt> | ||
+ | **<tt>continue</tt> oznacza: przerwij działania na aktualnym elemencie, i wróć do początku bloku biorąc kolejny element. Jeśli już zabrakło elementów, przejdź do bloku <tt>else</tt>, albo (gdy go nie ma) do polecenia następnego po pętli | ||
+ | |||
+ | <blockquote><small> | ||
+ | Blok <tt>else</tt> w pętli <tt>for</tt> jest stosunkowo rzadko widywany. Nawet wielu dość biegłych w Pythonie nie wie o tej opcji. | ||
+ | </small></blockquote> | ||
+ | |||
+ | A co, jeśli chcielibyśmy za pomocą pętli <tt>for</tt> (lub inaczej) zmienić w jakiś sposób skład samej sekwencji? Na przykład: | ||
+ | |||
+ | <source lang=python> | ||
+ | for x in lista: | ||
+ | x = x + 1 | ||
+ | </source> | ||
+ | |||
+ | '''TO NIE ZADZIAŁA''' - w tym sensie, że ''liosta'' będzie dalej miała te same elementy co poprzednio, a nie - powiększone o 1. W istocie operacja taka nic nie osiąga - oprócz tego, że po jej zakończeniu nazwa ''x'' ma wartość ostatniego elementu listy, powiększonego o 1. To samo można dostać bez pisania pętli. | ||
+ | |||
+ | Jak więc osiągnąć zmianę - przeliczenie - wszystkich elementów sekwencji wg. jakiejś reguły (np. powiększ każdy z nich o 1)? | ||
+ | |||
+ | Pożytecznym sposobem tworzenia sekwencji jest funkcja <tt>range</tt>: | ||
+ | |||
+ | <source lang=python> | ||
+ | for x in range(3): | ||
+ | print(x) | ||
+ | → 0 | ||
+ | → 1 | ||
+ | → 2 | ||
+ | </source> | ||
Wersja z 12:27, 29 cze 2016
Sekwencje i iteracja
Sekwencje to typ danych charakteryzujący się tym, że składają się z elementów zgromadzonych w pewnej kolejności. Elementem sekwencji może być cokolwiek (w tym - inna sekwencja), ale w najprostszym przypadku elementami tymi są liczby.
Sekwencje to szczególny przypadek kolekcji - takich typów danych, które składają się z elementów, ale niekoniecznie są one uporządkowane. Innym przykładem kolekcji jest zbiór (set).
Najczęściej używanym typem sekwencji jest lista (list). Listę można stworzyć (i zapamiętać) np. nadając jej pewien początkowy skład:
numerki = [0, 1, 2, 3, 5, 8]
To co stoi po prawej stronie znaku równości to literalny zapis listy - ciąg elementów, oddzielonych przecinkami, wewnątrz pary nawiasów kwadratowych.
Z listy - podobnie jak z każdej sekwencji - można pobrać element stojący w dowolnej pozycji:
print(numerki[4])
→ 5
Uwaga: pozycje numerowane są kolejnymi liczbami naturalnymi, począwszy od zera - podobnie, jak w większości języków programowania.
Można też podmienić istniejący element na inny:
numerki[0] = -1
print(numerki)
→ [-1, 1, 2, 3, 5, 8]
a nawet przedłużyć ją o kolejny element:
numerki.append(13)
print(numerki)
→ [-1, 1, 2, 3, 5, 8, 13]
oraz usunąć element (skracając listę):
del numerki[0]
print numerki
→ [1, 2, 3, 5, 8, 13]
Jest jeszcze sporo innych ,,gotowych do użytku" operacji na listach. Ale najważniejsza cecha listy jest taka: można zmieniać jej skład, a nawet długość, a pozostaje ona tą samą listą. Nawet jeśli występuje w programie pod więcej niż jedną nazwą.
Pętla for
Naczelne zastosowanie listy (czy ogólniej -sekwencji), to iteracja - czyli wykonanie jakiejś operacji dla każdego elementu. I tak wygląda najprostszy rodzaj iteracji - Pętla for:
for x in numerki:
print(x)
Zamiast print(x) pętlę for może tworzyć dowolny blok instrukcji, zgodnie z zasadami jakie już poznaliśmy przy omawianiu instrukcji warunkowej. Cały blok tworzący wnętrze pętli będzie wykonany wielokrotnie, tyle razy, ile elementów ma lista, a za każdym razem pod nazwę stojącą bezpośrednio po słowie for podstawiony będzie kolejny element listy (przywołanej po słowie in) - kolejny, tzn. zgodnie z kolejnością, w jakiej umieszczone są one w liście.
Inny, znany nam już rodzaj sekwencji to napis (string), zwany czasami łańcuchem znakowym. Napis składa się ze znaków, i jest w szczególności sekwencją, której elementami są znaki. Analogicznie jak w przypadku listy, można pobierać znaki stojące na poszczególnych pozycjach w napisie. Nie można natomiast podmieniać znaków w napisie, ani ich usuwać bądź dopisywać: w odróżnieniu od listy, napis raz utworzony jest niezmienny. Można go zastąpić innym napisem, i ewentualnie opatrzyć ten nowy napis tą samą nazwą, ale nie da się go zmodyfikować. I nie jest to dzielenie włosa na czworo, własność ta ma namacalne konsekwencje:
napis1 = 'abc'
napis2 = napis1
napis1 = 'ABC'
print(napis1, napis2)
→ ABC abc
# dla porównania, listy:
lista1 = ['a', 'b', 'c']
lista2 = lista1
lista1[0] = 'A'
print(lista1, lista2)
→ ['A', 'b', 'c'] ['A', 'b', 'c']
Powraca jeszcze raz pytanie: czym są poszczególne znaki? Tzn. jaki typ danych reprezentują? Otóż w Pythonie pojedyncze znaki też są po prostu napisami, tyle że o długości jeden. Poza długością nic ich szczególnie nie wyróżnia. Ta uwaga jest na użytek tych z Was, którzy znają jakiś inny język programowania, gdyż w wielu z nich znak jest oddzielnym, innym niż napis typem danych.
Pętlę for można zatem zastosować do napisu - zamiast do listy, wówczas w kolejnych iteracjach będą uwzględniane kolejne znaki, a których składa się napis.
Ogólna postać pętli for
for element in sekwencja:
<blok instrukcji>
else:
<blok instrukcji>
- Pierwszy blok instrukcji będzie wykonany tyle razy, ile elementów ma sekwencja
- Za każdym razem nazwa element oznaczać będzie kolejny element sekwencji, zgodnie z ich porządkiem
- sekwencja może być pusta; nie jest to błąd, ale wtedy pierwszy blok nie będzie wykonany ani razu
- Gdy elementy sekwencji się wyczerpią, wykonany zostanie blok po else
- Blok else (wraz z linijką go otwierającą) jest opcjonalny (niekonieczny)
- W pierwszym bloku mogą wystąpić specjalne polecenia: break i continue
- break znaczy: przerwij pętlę natychmiast, pomiń wszystkie pozostałe elementy sekwekcji, pomiń również ewentualny blok else
- continue oznacza: przerwij działania na aktualnym elemencie, i wróć do początku bloku biorąc kolejny element. Jeśli już zabrakło elementów, przejdź do bloku else, albo (gdy go nie ma) do polecenia następnego po pętli
Blok else w pętli for jest stosunkowo rzadko widywany. Nawet wielu dość biegłych w Pythonie nie wie o tej opcji.
A co, jeśli chcielibyśmy za pomocą pętli for (lub inaczej) zmienić w jakiś sposób skład samej sekwencji? Na przykład:
for x in lista:
x = x + 1
TO NIE ZADZIAŁA - w tym sensie, że liosta będzie dalej miała te same elementy co poprzednio, a nie - powiększone o 1. W istocie operacja taka nic nie osiąga - oprócz tego, że po jej zakończeniu nazwa x ma wartość ostatniego elementu listy, powiększonego o 1. To samo można dostać bez pisania pętli.
Jak więc osiągnąć zmianę - przeliczenie - wszystkich elementów sekwencji wg. jakiejś reguły (np. powiększ każdy z nich o 1)?
Pożytecznym sposobem tworzenia sekwencji jest funkcja range:
for x in range(3):
print(x)
→ 0
→ 1
→ 2