Operatory logiczne są "szybkie", ewaluacja wyrażenia jest przerywana gdy znana jest jego wartość logiczna.
- Instrukcja warunkowa if
if warunek_1:
#lista instrukcji
elif warunek_2:
#lista instrukcji
elif warunek_3:
#lista instrukcji
...
else:
#lista instrukcji
Dwukropki na końcu wierszy zaczynajacych się od if, elif oraz else są obowiązkowe, wcięcia w pozostałych wierszach również. Blok
else nie jest obowiązkowy, może też nie być żadnego bloku elif. Warunki (warunek_1,warunek_2, ...) nie muszą się wykluczać. Szukany
jest pierwszy spełniony warunek, wykonywane są instrukcje do najbliższego elif lub else. Żadna lista instrukcji nie może być pusta, przydatne bywa
słowo kluczowe pass będące odpowiednikiem kodu {} w C, C++, C#, Javie.
Program obliczający pierwiastki rzeczywiste równania ax2 + bx +c = 0, gdy jest ono kwadratowe (tzn. a ≠ 0), a "milczący" gdy a == 0 można
napisać tak:
delta = ...
if not a == 0:
if delta > 0:
...
elif delta == 0:
...
else:
...
lub tak
delta =...
if a == 0:
pass
elif delta > 0:
...
elif delta == 0:
...
else:
...
Przykład, konwersja podanej przez użytkownika liczby całkowitej do innego systemu liczbowego.
x = input('Podaj liczbe: ')
b = input('Podaj podstawe (<=16): ')
if b>16:
print("Zbyt duza podstawa")
elif b<=1:
print("Zbyt mala podstawa")
else:
if x<0:
znak = "-"
x*=-1
else:
znak = ""
lista = []
while x>0:
cyfra = x % b
x/=b
if cyfra < 10:
lista.append(str(cyfra))
elif cyfra == 10:
lista.append('A')
elif cyfra == 11:
lista.append('B')
elif cyfra == 12:
lista.append('C')
elif cyfra == 13:
lista.append('D')
elif cyfra == 14:
lista.append('E')
elif cyfra == 15:
lista.append('F')
lista.reverse()
print znak + "".join(lista)
Dwie uwagi:
Spis treści
- Pętla for
for x in kolekcja:
#lista instrukcji
Elementy kolekcji moga być dowolnego typu, niekoniecznie musi to być ciąg arytmetyczny liczb.
- Kolekcja, po której iterujemy nie istnieje wcześniej. Tworzymy ją np. funkcją range:
for i in range(1,6):
print '*'*i
*
**
***
****
*****
- Kolekcja, po której iterujemy istnieje wcześniej.
l = ['t','e','s','t']
for x in l:
x = x.upper()
print x
print l
T
E
S
T
['t', 'e', 's', 't']
Jak widać lista l nie zmieniła się, tzn. przy iterowaniu kolekcji działamy na kopiach jej elementów. Zmianę wszystkich liter na duże możemy w
liście napisów uzyskać tak:
l = ['t','e','s','t']
for x in range(len(l)):
l[i] = l[i].upper()
print l
['T', 'E', 'S', 'T']
Należy zachować dużą ostrożność, jeżeli iterując po kolekcji próbujemy zmieniać kolekcję dodając do niej nowe elementy, łatwo uzyskać nieskończoną pętlę.
l = [1]
n = 2
for x in l:
l.append(n)
n+=1
if len(l) > 100:
break
Po wykonaniu powyższego kodu lista l zawiera 101 liczb (1,2,...,101). Słowo kluczowe break przerywa wykonywanie pętli (najbardziej
wewnętrznej pętli, jeżeli pętle są zagnieżdżone). Bez instrukcji break powyższa pętla byłaby nieskończona. Inny sposób uniknięcia nieskończonej pętli,
to użycie polecenia continue. Słowo kluczowe continue wymusza przejście do nastepnego kroku iteracji (zmienna sterująca przyjmuje
kolejną wartość).
l = [1]
n = 2
for x in l:
if len(l) > 100
continue
l.append(n)
n+=1
Jeżeli chcemy dodawać elementy do kolekcji, po której iterujemy, to bezpieczniej jest posłużyć się kopią kolekcji. Taką kopię można utworzyć "w locie":
l=["sTop","FOTel"]
for w in l[:]:
l.remove(w)
l.append(w.lower())
l.append(w.upper())
l ⇒ ['stop',' STOP', 'fotel', 'FOTEL']
Operator zakresu [:] stworzył kopię całej listy l.
Iteratory i generatory
W tle pętli for występuje tzw. iterator i jego metoda next(). Tradycyjny (krótki) zapis pętli:
for e in 'kroki'
print e,
⇒ k r o k i
Z jawnym wykorzystaniem iteratora:
it = iter('kroki')
while True
try:
print it.next(),
except:
break
Pętla for korzysta zazwyczaj z domyślnego iteratora związanego z kolekcją. Możemy wymusić korzystanie z innego iteratora. Są dwa
sposoby takiego wymuszenia:
- zdefiniowanie tzw. generatora, generator wygląda jak zwyczajna funkcja, tylko zamiast słowa return używamy słowa kluczowego,
yield:
def odTylu(dane):
for i in range(len(dane)-1,-1,-1):
yield dane[i]
(Wywołanie range(10,-1,-1) zwraca listę [10,9,...,0]). Wywołanie generatora poza pętlą jest mało przydatne:
odTylu('kroki') ⇒ <generator object odTylu at 0x0122C710>
Jeżeli użyjemy go w pętli, to automatycznie powstaną (niestandardowe) funkcje iter,
next, a po przejściu kolekcji geenerowany będzie wyjątek StopIteration.
for c in odTylu('koma'):
print c,
⇒ a m o k
for i in odTylu(range(3,13)):
print i,
⇒ 12 11 10 9 8 7 6 5 4 3
- napisanie własnej klasy z metodami __iter__ oraz next, ta druga musi po przejściu kolekcji generować wyjątek
StopIteration:
class CoDrugi:
"Iterator, który zwraca co drugi element"
def __init__(self,dane):
self.dane = dane
self.index = -2
def __iter__(self):
return self
def next(self):
self.index = self.index+2
if self.index>=len(self.dane):
raise StopIteration
return self.dane[self.index]
Pierwszy wiersz w definicji klasy, to opis jej działania (krótka dokumentacja).
CoDrugi.__doc__ ⇒ 'Iterator, kt\xf3ry zwraca co drugi element'
for c in CoDrugi("mama"):
print c,
⇒ m m
.
Spis treści
- Pętla while
while warunek:
#lista instrukcji
Pętla wykonywana jest tak długo dopóki spełniony jest warunek, przy pisaniu warunku możemy korzystać ze słów kluczowych not, and oraz
or, ze zmiennych logicznych i ze wszystkich innych zmiennych. W warunkach wykonywana jest niejawna konwersja na typ logiczny bool. Zmienna
jest "prawdziwa", jeżeli jest niepusta.
l = []
if l:
print "test" ⇒
l.append("cokolwiek")
if l:
print "test" ⇒ 'test'
Przykład:
l = "Jeżeli dziś wtorek to jesteśmy w Belgii".split()
l.reverse()
prefix = ""
while l:
print prefix + l.pop()
prefix+=" "
Jeżeli
dziś
wtorek
to
jesteśmy
w
Belgii
Pierwszy wiersz (l = "Jeżeli ...".split()) utworzył liste słów o nazwie l. Pętlę można opisać tak: dopóki lista słów l jest niepusta, to wyświetl
ostatni wyraz listy (poprzedzając go pewna ilością spacji) i usuń ten wyraz z listy.
Znaczenie słów kluczowych break i continue jest w pętli while analogiczne jak w pętli for -
break przerywa wykonywanie pętli, continue powoduje pominięcie kolejnych instrukcji i ponowne sprawdzenie warunku.
i = 1
while True:
i+=1
if i%2 == 1:
continue //dalsze instrukcje są pomijane gdy i jest nieparzyste, w szczególności dla i == 11 pętla nie zostanie przerwana
print i,i*i
if i > 10:
break
2 4
4 16
6 36
8 64
10 100
12 144
- Konstrukcje l = [wyrażenie for element in kolekcja] oraz l = [wyrażenie for element in kolekcja if warunek],
wyrażenie musi zwracać (wyliczać) wartość. Konstrukcje te tworzą listy, pierwsza z nich jest skróconym zapisem takiej pętli:
l = []
for element in kolekcja:
l.append(wyrażenie)
a druga, takiej:
l = []
for element in kolekcja:
if warunek:
l.append(wyrażenie)
Utworzenie listy pierwiastków kwadratowych √x, liczby x dzielą się przez 4 i są postaci y3, 1 ≤ y ≤ 20.
from math import sqrt
l = [sqrt(x) for x in [y*y*y for y in range(1,21)] if x%4 == 0]
l
⇒ [2.8284271247461903, 8.0, 14.696938456699069, 22.627416997969522, 31.622776601683793, 41.569219381653056, 52.38320341483518, 64.0,
76.36753236814714, 89.44271909999159]
Instrukcja from math import sqrt jest konieczna by móc korzystać z funkcji matematycznej sqrt.