A while ciklusról

A while ciklust elöltesztelő ciklusnak is nevezik.

In [1]:
n = 1000
a = 1
while a ** 3 < n:
    print(a ** 3, end=' ')  # egy sorba kerülnek
    a = a + 1
print("vege")
1 8 27 64 125 216 343 512 729 vege

Tudunk írni olyan ciklust, mely addig olvas be számokat míg valamilyen kritérium nem teljesül:

Feladat: Írjunk olyan kódot, mely addig olvas be számokat míg egyszer 0-t nem kap, ekkor megáll és kiírja a kapott számok összegét.

In [2]:
n = 0
a = float(input())          # beolvasó, kovertáló kód először
while a != 0:
    n = n + a
    a = float(input())      # ugyan az a kód másodszor!
print(n)
1
2
0
3.0

A fenti példában a kód egy részét meg kellett ismételni: egyszer szerepelt a ciklus előtt, egyszer a ciklusban. Ez nem tűnik hatékony és bölcs megoldásnak.

Feladat: Írjuk át az előző programot kódismétlés nélkül!

In [3]:
n = 0
while True:                 # a ciklus eleje
    a = float(input())      # beolvas, számmá konvertál
    if a == 0:              # kiugrás feltétele
        break               # kiugrás
    n += a                  # ha nem ugrott ki a ciklusból (ua. mint n = n + a)
print(n)
1
2
0
3.0

A más nyelvekben használt (néha hátultesztelőnek nevezett) utasítások, mint a

do ... while ...

vagy

do... until ...

a Pythonból hiányzik, pontosabban szükségtelennek ítéltetett, mert a

while True:
    <előkészítő parancsok>
    if <kiugrás feltétele>:
        break
    <további parancsok>

szerkezetű kód megadja a fenti kódok adta lehetőségeket, ezért új parancs bevezetése semmi haszonnal nem járna.

Programozási tételek

Általalánosan megfogalmazott gyakran használt rövid algoritmusok

Összegzés tétele

Bár a név ezt sugallja, de nem feltétlen csak összegzésre használható. Ha van egy számokból (vagy bármi másból) álló sorozatunk és valamilyen szempontból összegezni akarjuk őket egy változóba, akkor beszélünk az összegzés tételéről.

Feladat: Olvassunk be 0-tól különböző számokat a standard inputról, és adjuk össze őket. A sorozat végét 0 jelölje.

In [4]:
sum = 0                 # akkumulátor
while True:             # ciklus eleje
    a = float(input())  # beolvasás
    if a == 0:          # a kiugrás feltétele
        break
    sum += a            # összegzés
print(sum)
1
2
0
3.0

Kérdés: Mit kell kapnunk, ha az összegzendő számok sorozata üres?

Nem csak szummázni lehet:

Feladat: Szorozzuk össze az standard inputról beolvasott számokat. Gondoljunk arra, hogy mit kell kapnunk eredményül, ha a számok sorozata üres? A sorozat végét most jelölje egy üres karakterlánc, azaz a beviteli mezőbe adott üres ENTER. Vigyázzunk, üres karakterlánc nem konvertálható számmá!

In [5]:
prod = 1                # akkumulátor
while True:             # ciklus
    a = input()         # beolvasás
    if a == "":         # a kiugrás feltétele
        break
    prod *= float(a)    # konvertálás és szorzás
print(prod)
1
2
345

690.0

Számlálás tétele

Adott valahány objektumunk (pl. számok) és ezek közül szeretnénk megszámolni az adott tulajdonsággal rendelkezőket (pl. a páratlanokat).

Feladat: Számoljuk meg, hogy egy 0-t nem tartalmazó egészekből álló számsorozatban hány páratlan szám van! A sorozat végét 0 jelölje.

In [6]:
db = 0                  # számláló
while True:             # ciklus
    a = int(input())    # beolvasás
    if a == 0:          # leállási feltétel
        break
    if a % 2 == 1:      # tulajdonság vizsgálata
        db += 1         # számláló növelése
print(db)
1
11
111
2
0
3

Feladat: Olvassunk be karakterláncokat egészen addig amíg egy üres szót nem kapunk az input mezőben. Számoljuk meg, hogy a beolvasott karakterláncok közül hány darabban található 'ő' betű!

In [7]:
db = 0        
while True:
    szo = input()
    if szo == "":
        break
    if "ő" in szo:
        db += 1
print(db)
erdő, mező
Erdős Pál
liget, fű, fa virág

2

Szélsőérték keresése

Adott objektumok egy sorozata, elemeinek szélsőértékét keressük valamilyen adott rendezés szerint.

Feladat: Pozitív valós számok sorozatából válasszuk ki a legnagyobbat! Ha a sorozat üres (azaz az első beolvasott szám nem pozitív), írjunk ki 0-t!

In [8]:
legnagyobb = 0
while True:              
    a = float(input())   # beolvasás
    if a <= 0:           # leállási feltétel
        break
    if legnagyobb < a:   # tulajdonság vizsgálata
        legnagyobb = a   # a legnagyobb frissítése (növelése)
print("A legnagyobb =", legnagyobb)
23
5432
2
-2
A legnagyobb = 5432.0

Ha tetszőleges valós számok között keressük a legnagyobbat, akkor az üres halmaz maximuma mínusz végtelen kell hogy legyen (vagy hibaüzenetet kell kapnunk – ennek módjait később tanuljuk).

In [9]:
legnagyobb = float('-inf')  # üres halmaz legnagyobb eleme -∞
while True:              
    a = input()             # beolvasás
    if a == "":             # leállási feltétel
        break
    f = float(a)            # csak itt konvertálunk
    if legnagyobb < f:      # tulajdonság vizsgálata
        legnagyobb = f      # a legnagyobb frissítése (növelése)
print("A legnagyobb =", legnagyobb)
-34
-2345
-6

A legnagyobb = -6.0

Eldöntés tétele

Azt vizsgáljuk, hogy adott elemek között szerepel-e egy bizonyos tulajdonságú. Például a prímtesztelésnél a lehetséges osztók voltak a lehetséges elemek és azt vizsgáltuk, hogy valamelyik osztja-e az adott számot.

Feladat: Írjunk programot, mely egy 1-nél nagyobb egész számról eldönti, hogy prímszám, vagy összetett!

In [10]:
n = int(input())         # a szám beolvasása
oszto = 2                # az osztó induló értéke
talalt = False           # találtunk osztót?
while oszto**2 <= n:     # ciklus a leállási feltétellel
    if n % oszto == 0:   # az oszto osztó?
        talalt = True    # találtunk egy osztót
        break            # kiugrunk
    oszto += 1           # következő lehetséges osztót
if not talalt:           # kiírás
    print("a(z) {0} prímszám".format(n))
else:
    print("a(z) {0} összetett szám".format(n))
499
a(z) 499 prímszám

Tételek kombinálása

Ezeket a tételeket általában kombinálni kell, hogy a bonyolultabb feladatokat meg tudjuk oldani. Természetesen nem csak ezek használatával lehet megoldani feladatokat, de kiindulásnak jó velük megismerkedni.

Feladat: Számoljuk meg, hogy hány prím van 2-től 1000-ig! Ehhez az eldöntés tételét ágyazzuk be a számlálás tételébe.

In [11]:
szam = 2                     # kezdőérték a számlálás tételéhez
primek_db = 0                # a számlálás tételének számlálója
while szam <= 1000:          # itt kezdődik a számlálás tétele
    oszto = 2                # a beágyazott eldöntés tétele kezdete
    osszetett = False        # a találatot jelző logikai változó
    while oszto**2 <= szam:      # az eldöntés tételének ciklusa
        if szam % oszto == 0:    # van osztója?
            osszetett = True
            break
        oszto += 1               # az eldöntés tételében léptetünk
    if not osszetett:        # ez már a számlálás tétele
        primek_db += 1       # a számláló növelése
    szam += 1                # és lépünk a következő elemre
print(primek_db)
168

Listák

A listákra gondolhatunk úgy, mint tárolókra, melyek több objektumot képesek tárolni úgy, hogy a sorrendjük is meg van adva. Egy listának sose adjuk a list nevet, mert az a típus és a listává konvertáló függvény neve.

In [12]:
lista = [1, 2, 5]
In [13]:
lista
Out[13]:
[1, 2, 5]

A listák elemeit szögletes zárójelbe tesszük és vesszővel választjuk el egymástól. Egy listának akárhány eleme lehet (akár 0 is), ezek az elemek akármilyen típusúak lehetnek (akár másik listák is):

In [14]:
lista = [1, 5.3, "kutya", [1, 2, 5], 12, "macska"]
In [15]:
lista
Out[15]:
[1, 5.3, 'kutya', [1, 2, 5], 12, 'macska']

Listák elemeinek elérése, részlisták

Lista egy adott elemét elérhetjük az indexe segítségével:

In [16]:
lista = ["a", "b", "c"]
print(lista[0], lista[1], lista[2])
a b c

Az indexelés 0-val kezdődik, azaz az első elem a 0 indexű.

Az utolsó elemet az n - 1 indexszel is elérjük, ahol n a lista hossza.

Az 1-től n-ig indexelés és a Python 0-tól indexelésének kapcsolatát mutatja a következő ábra:

 ____ ____ ____ ____ ____  
|    |    |    |    |    | 
| e1 | e2 | e3 |....| en | 
|____|____|____|____|____| 
Λ    Λ    Λ    Λ    Λ    Λ 
0    1    2    ... n-1   n 
-n  1-n  2-n        -1
In [17]:
print(lista[-1], lista[-2], lista[-3])
c b a

Egy lista részlistáját is lekérhetjük, az indextartományt alulról zárt, fölülről nyílt intervallumnak tekintjük:

In [18]:
lista = [0, 1, 2, 3, 4, 5]
print(lista[1:3])       # 1-től, a 3-asig, de a 3-as már nem lesz benne
print(lista[2:])        # a 2-es indextől a lista végéig
print(lista[:3])        # a lista elejétől a 3-asig, a 3-as nem lesz benne
print(lista[0:4:2])     # 1-től a 4-es indexűig 2-esével
print(lista[-1::-1])    # az utolsótól az elejéig visszafelé 1-esével
[1, 2]
[2, 3, 4, 5]
[0, 1, 2]
[0, 2]
[5, 4, 3, 2, 1, 0]

Listákat ugyanúgy lehet összefűzni mint stringeket:

In [19]:
print([1, 2, 5] + [8, 5, 3])
[1, 2, 5, 8, 5, 3]

Az eddigi listaműveletek működnek stringekkel is:

In [20]:
s = "trió"
print(s[1:4])
print(s[-2::-1] + s[-1])
print(s[::2])
print(s[1::2])
rió
irtó
ti
ró

Annyi különbség viszont van, hogy míg a listák változtatható (mutable) adattípusok, a stringek nem változtathatók (immutable). Tehát listának megváltoztathatjuk az elemeit:

In [21]:
lista = [1, 2, 5]
lista[1] = 200
print(lista)
[1, 200, 5]

Ugyanezt stringekkel nem tehetjük meg:

In [22]:
s = "trió"
s[0] = "b"
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-22-2fdd10b466fc> in <module>
      1 s = "trió"
----> 2 s[0] = "b"

TypeError: 'str' object does not support item assignment

Listakezelés metódusai

A listák kényelmes kezeléséhez tanuljuk meg néhány alapvető függényt / metódust.

Range

A range objektum lista létrehozására használható. Ún. lusta bejárható (lazy iterable) objektum (de nem iterátor, amit később fogunk tanulni). Az bejárható arra utal, hogy ciklus futtatható az elemein, a lusta arra, hogy az elemek csak ciklusonként, egyesével lesznek kiszámolva. A list függvény listává konvertálja a range objektumot:

In [23]:
list(range(4))
Out[23]:
[0, 1, 2, 3]
In [24]:
range(4) == [0, 1, 2, 3]
Out[24]:
False
In [25]:
list(range(4, 10))
Out[25]:
[4, 5, 6, 7, 8, 9]
In [26]:
list(range(3, 15, 3))
Out[26]:
[3, 6, 9, 12]

A range függvénynek három argumentum adható meg:

range(start, end, step)

amelyek jelentése a részlisták lekérésénél használtakhoz hasonlóan működik. Ha csak egy paraméter van megadva, akkor az az end, ha kettő akkor azok a start és az end.

A range objektum ugyanúgy indexelhető, mint egy lista:

In [27]:
range(0, 5, 2)[2]
Out[27]:
4
In [28]:
range(1, 10, 2)[1::2]
Out[28]:
range(3, 11, 4)
In [29]:
list(range(1, 10, 2)[1::2])  # [1, 3, 5, 7, 9] -> [3, 7]
Out[29]:
[3, 7]

Elemek hozzáadása, törlése

Az append metódussal új elemet fűzhetünk egy létező lista végére:

In [30]:
lista = [1, 2, 5]
lista.append(4)
print(lista)
[1, 2, 5, 4]
In [31]:
l = []
while True:
    a = input(a)
    if a == "":
        break
    l.append(a)
print(l)
alma
almakörte
körte123
123
['alma', 'körte', '123']

Az insert metódussal adott indexű helyre illeszthetünk be új elemet:

In [32]:
lista = [1, 2, 3, 4]
lista.insert(2, "X")
print(lista)
[1, 2, 'X', 3, 4]

A pop metódussal adott indexű elemet törölhetünk a listából. A függvény a törölt elemet adja vissza értékül. Üres argumentummal meghívva az utolsó elemet törli.

In [33]:
print(lista.pop(2))
print(lista)
X
[1, 2, 3, 4]
In [34]:
print(lista.pop())
print(lista)
4
[1, 2, 3]

A remove metódussal adott elem első előfordulását törölhetjük a listából:

In [35]:
lista = [1, 2, 3, 2, 2, 5]
lista.remove(2)
print(lista)
[1, 3, 2, 2, 5]
In [36]:
while 2 in lista:
    lista.remove(2)
print(lista)
[1, 3, 5]

Megadott indexű elemek törlésére a del parancs is használható:

In [37]:
lista = list(range(8))
del lista[::2]
print(lista)
del lista[1::2]
print(lista)
del lista[:]            # töröl mindent, ua. mint lista.clear()
print(lista)
[1, 3, 5, 7]
[1, 5]
[]

Egyéb műveletek listákkal

A len függvénnyel lekérhetjük egy lista hosszát:

In [38]:
lista = [1, 2, 5]
print(len(lista))
3

A count metódussal lekérhetjük, hogy egy adott elemből hány darab van a listában:

In [39]:
lista = [1, 2, 3, 4, 1, 2, 1, 4, 5, 1, 3, 2, 4]
print(lista.count(1), lista.count(4), lista.count(15))
4 3 0

A sort metódussal rendezhetjük a lista elemeit, ekkor az eredeti lista megváltozik. A sorted függvény új rendezett litát hoz létre:

In [40]:
lista = [1, 2, 3, 4, 1, 2, 1, 4, 5, 1, 3, 2, 4]
lista.sort()
print(lista)
[1, 1, 1, 1, 2, 2, 2, 3, 3, 4, 4, 4, 5]
In [41]:
lista = [1, 2, 3, 4, 1, 2, 1, 4, 5, 1, 3, 2, 4]
sorted(lista)
Out[41]:
[1, 1, 1, 1, 2, 2, 2, 3, 3, 4, 4, 4, 5]
In [42]:
print(lista)
[1, 2, 3, 4, 1, 2, 1, 4, 5, 1, 3, 2, 4]

For ciklus

Pythonban a for ciklus és a listák erősen összefüggnek. A for ciklus listán (és egyéb bejárható objektumokon) fut végig.

for <ciklusváltozó> in <bejárható objektum>:
    <állítások>
else:
    <állítások>
In [43]:
lista = ["kutya", "macska", "egér", "tücsök"]
for elem in lista:
    print(elem, end=" -> ")
print("...")
kutya -> macska -> egér -> tücsök -> ...
In [44]:
for elem in range(0,10,2):
    if elem % 2 == 1:
        break
    print(elem, end=" ")
else:
    print("mind páros")
0 2 4 6 8 mind páros
In [45]:
lista = [0, 2, 4, 5, 6, 8]
for elem in lista:
    if elem % 2 == 1:
        break
    print(elem, end=" ")
else:
    print("mind páros")
0 2 4 

Ha az indexekkel szeretnénk végigmenni a listán, akkor használhatjuk a range metódust:

In [46]:
# elemeken
lista = [2, 3, 5, 7, 11]
for e in lista:
    print(e, end=" ")
2 3 5 7 11 
In [47]:
# indexeken
lista = [2, 3, 5, 7, 11]
for i in range(len(lista)):
    print(lista[i], end=" ")
2 3 5 7 11 

A range(len(lista)) épp a lista indexeit adja vissza és a for ciklus ezeken megy végig:

In [48]:
lista = [2, 3, 5, 7, 11]
for i in range(len(lista)):
    print("index: ", i, " elem: ", lista[i])
index:  0  elem:  2
index:  1  elem:  3
index:  2  elem:  5
index:  3  elem:  7
index:  4  elem:  11

Programozási tételek listákkal

Összegzés tétele

In [49]:
lista = [1, 2, 5]
n = 0
for e in lista:
    n += e
print(n)
8

Számlálás tétele

In [50]:
lista = [1, 2, 5, 6, 4, 6, 7, 8]
db = 0
for e in lista:
    if e % 3 == 0:
        db += 1
print(db)
2

Szélsőérték keresése

In [51]:
lista = [1, 2, 5, 6, 15, 4, 6, 7, 8]
legnagyobb = lista[0]    # arra az esetre, ha a lista nem üres
for e in lista[1:]:
    if legnagyobb < e:
        legnagyobb = e
print(legnagyobb)
15

Eldöntés tétele

In [52]:
lista = [0, 2, 4, 5, 6, 8]
for elem in lista:
    if elem % 2 == 1:
        print("nem mind páros")
        break
else:
    print("mind páros")
nem mind páros

Tételek kombinációja

Számoljuk meg, hogy azokban a karakterláncokban, melyekben van 'ő' betű, összesen hány darab 'e' betű van!

In [53]:
szavak = ["betörő", "majomparádé", 
          "elment az őrszem", "elembertelenedett"]
db = 0
for szo in szavak:
    if "ő" in szo:
        for i in range(len(szo)):
            if szo[i] == "e":
                db += 1
print(db)
4

A count metódussal egyszerűbben is meg lehet oldani (ez jóformán egy beépített számlálás tétele egyszerűbb esetekre):

In [54]:
szavak = ["betörő", "majomparádé", 
          "elment az őrszem", "elembertelenedett"]
db = 0
for szo in szavak:
    if "ő" in szo:
        db += szo.count("e")
print(db)
4