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,  # a vessző miatt 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:

In [2]:
a = input()
while a != 5:
    print a
    a = input()
6
6
4
4
5

Írjunk most 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 [3]:
n = 0
a = input()         # kód először
while a != 0:
    n = n + a
    a = input()     # kód másodszor
print n
3
6
4
0
13

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.

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 egyenértékű velük, és új parancs bevezetése semmi haszonnal nem járna.

Például az előző kód így írható át kódismétlés nélküli módon:

In [4]:
n = 0
while True:       # a ciklus eleje
    a = input()   # ez a kód csak egyszer szerepel, nincs kódismétlés
    if a == 0:    # a ciklusból való kiugrás feltétele
        break     # a ciklus vége
    n += a        # a ciklus további utasításai (ha a kiugrás feltétele nem teljesült)
print n
6
4
3
0
13

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ám (vagy bármi más) sorozatunk és valamilyen szempontból összegezni akarjuk őket egy változóba, akkor beszélünk az összegzés tételéről.

In [5]:
n = 0            # akkumulátor
a = input()      # első beolvasása
while a != 0:    # leállási feltétel
    n = n + a    # összegzés
    a = input()  # későbbiek beolvasása
print n
3
2
0
5

Nem csak szummázni lehet:

In [6]:
n = 1            # akkumulátor
a = input()      # első beolvasása
while a != 1:    # leállási feltétel
    n = n * a    # összegzés
    a = input()  # későbbiek beolvasása
print n
4
6
2
1
48

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).

In [7]:
db = 0               # számláló
a = input()          # első beolvasása
while a != 0:        # leállási feltétel
    if a % 2 == 1:   # tulajdonság vizsgálata
        db += 1      # számláló növelése
    a = input()      # későbbiek beolvasása
print db
3
4
5
6
0
2

Nézzünk egy bonyolultabb példát stringekkel. Olvassunk be szavakat egészen addig amíg egy üres stringet nem olvasunk be. Számoljuk meg, hogy a beolvasott szavak közül hány darabban található 'e' betű!

In [8]:
db = 0        
szo = raw_input()        
while szo != "":      
    if "e" in szo:  
        db += 1   
    szo = raw_input()   
print db
eper
szilva
alma

1

Szélsőérték keresése

Adott objektumok egy sorozata, ezeknek a szélsőértékét keressük valamilyen szempontból.

Például a következő feladatban 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 [9]:
legnagyobb = 0
a = input()              # első beolvasása
while a > 0:             # leállási feltétel
    if legnagyobb < a:   # tulajdonság vizsgálata
        legnagyobb = a   # a legnagyobb frissítése (növelése)
    a = input()          # a következő beolvasása
print "A legnagyobb:", legnagyobb
3
5
2
0
A legnagyobb: 5

Kódismétlés nélküli változat:

In [10]:
legnagyobb = 0           # inicializálás: a maximum lehetséges legkisebb értéke
while True:              
    a = 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
3
5
2
0
A legnagyobb: 5

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ím tesztelésnél a lehetséges osztók voltak a lehetséges elemek és azt vizsgáltuk, hogy valamelyik osztja-e az adott számot.

In [11]:
n = input()                    # a szám beolvasása
a = 2                          # a változó amivel végigfutunk a lehetséges osztókon
talalat = False                # megtaláltuk-e a keresett elemet
while a < n and not talalat:   # leállási feltétel, ha megtaláltuk akkor is leállunk
    if n % a == 0:             # a keresett elem a beolvasott szám osztója
        talalat = True         # ha megtaláltuk akkor a találatot igazra állítjuk
    a += 1                     # vizsgáljuk a következő elemet
print not talalat              # azért a negáltját írjuk ki, mert valójában összetettséget vizsgáltunk
23
True

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.

Számoljuk most 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 [12]:
szam = 2                                     # az első elem amit a számlálás tételénél vizsgálunk
primek_db = 0                                # a számlálás tételének számlálója
while szam < 10000:                           # itt kezdődik a számlálás tétele
    oszto = 2                                # ez már a beágyazott eldöntés tételének a kezdeti eleme
    osszetett = False                        # ez pedig a találatot jelző változója
    while oszto < szam and not osszetett:    # az eldöntés tételének ciklusa
        if szam % oszto == 0:
            osszetett = True
        oszto += 1                           # az eldöntés tételében lépünk a következő elemre
    if not osszetett:                        # itt már befejeződött a beágyazott eldöntés tétele
        primek_db += 1                       # ez a számlálás tételének a feltétele és növelése
    szam += 1                                # a számlálás tételében lépünk a következő elemre
print primek_db
1229

Listák

A listákra gondolhatunk úgy, mint tárolókra, melyek több objektumot képesek tárolni, például számokat:

In [13]:
lista = [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"]

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

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

In [15]:
lista = ["a", "b", "c"]
print lista[0]
print lista[1]
print lista[2]
a
b
c

Amint látható az indexek számozása 0-tól kezdődik, így az első elemet a 0 indexszel érhetjük el. Míg az utolsó elemet az n - 1 indexszel érjük el, ahol n a lista hossza.

Egy lista részlistáját is lekérhetjük:

In [16]:
lista = ["a", "b", "c", "d", "e", "f"]
print lista[1:3]       # az 1-es indextől a 3-asig kérjük le az elemeket, 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-as indexig, a 3-as indexű elem nem lesz benne
print lista[0:4:2]     # az első elemtől a 4-es indexűig kérjük le kettesével
print lista[-1::-1]    # az utolsó elemtől (negatív index visszafelé lépked -1-től kezdve) az elejéig -1-esével
['b', 'c']
['c', 'd', 'e', 'f']
['a', 'b', 'c']
['a', 'c']
['f', 'e', 'd', 'c', 'b', 'a']
In [17]:
lista[-2]
Out[17]:
'e'

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

In [18]:
print [1, 2, 5] + [8, 5, 3]
[1, 2, 5, 8, 5, 3]

Minden eddigi művelet működik stringekkel is:

In [19]:
s = "kutya"
print s[2]
print s[1:4]
print s[-1::-1]
t
uty
aytuk

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 [20]:
lista = [1, 2, 5]
lista[2] = 3
print lista
[1, 2, 3]

Viszont ugyanezt stringekkel nem tehetjük meg:

In [21]:
s = "kutya"
s[1] = "a"
print s
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)
<ipython-input-21-7b4cb7bf4263> in <module>()
      1 s = "kutya"
----> 2 s[1] = "a"
      3 print s

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 függvénnyel listát hozhatunk létre. Általában számsorozatok létrehozására hasznos:

In [22]:
print range(4)
[0, 1, 2, 3]
In [23]:
print range(4, 10)
[4, 5, 6, 7, 8, 9]
In [24]:
print range(3, 15, 3)
[3, 6, 9, 12]

Amint látható, a részlisták lekéréséhez hasonlóan működik. Ha csak egy paramétert adunk meg, akkor 0-tól indulva hozza létre a listát a megadott számig (a szám már nem lesz benne). Létrehozhatunk adott számtól listát, és adott lépésközzel is.

Természetesen ugyanúgy manipulálható, mint a manuálisan létrehozott lista:

In [25]:
lista = range(1, 4)
lista[2] = 5
print lista
[1, 2, 5]

Új elemek felvétele / törlése

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

In [26]:
lista = [1, 2, 5]
lista.append(4)
print lista
[1, 2, 5, 4]
In [27]:
l = []
a = input()
while a != 0:
    l.append(a)
    a = input()
print l
1
2
15
3
0
[1, 2, 15, 3]

Az insert metódussal adott indexre illeszthetünk be új elemet:

In [28]:
lista = [1, 2, 5]
lista.insert(1, 1.5)
print lista
[1, 1.5, 2, 5]

A pop metódussal adott indexű elemet törölhetünk a listából:

In [29]:
lista = [1, 2, 4, 2, 5]
lista.pop(2)
print lista
[1, 2, 2, 5]

A remove metódussal adott elemet törölhetünk a listából:

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

Egyéb műveletek listákkal

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

In [32]:
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 [33]:
lista = [1, 2, 3, 4, 1, 2, 1, 4, 5, 1, 3, 2, 4]
print lista.count(1)
print lista.count(4)
print lista.count(15)
4
3
0

A sort metódussal rendezhetjük a listát:

In [34]:
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]

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:

In [35]:
lista = [1, 2, 5, "kutya"]
for elem in lista:
    print elem
1
2
5
kutya

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

In [36]:
lista = [1, 2, 5, "kutya"]
for i in range(len(lista)):
    print lista[i]
1
2
5
kutya

Miért is működik ez? Gondoljuk végig, hogy a range(len(lista)) pont a lista indexeinek a listáját hozza létre és a for ciklus ezeken megy végig:

In [37]:
lista = [1, 2, 5, "kutya"]
for i in range(len(lista)):
    print "index: ", i, " elem: ", lista[i]
index:  0  elem:  1
index:  1  elem:  2
index:  2  elem:  5
index:  3  elem:  kutya

Programozási tételek listákkal

Összegzés tétele

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

Számlálás tétele

In [39]:
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 [40]:
lista = [1, 2, 5, 6, 15, 4, 6, 7, 8]
legnagyobb = lista[0]
for e in lista:
    if legnagyobb < e:
        legnagyobb = e
print legnagyobb
15

Eldöntés tétele

In [41]:
szam = input()
osszetett = False
for oszto in range(2, szam):
    if szam % oszto == 0:
        print oszto
        osszetett = True
        break
print not osszetett
22
2
False

Tételek kombinációja

Számoljuk meg, hogy adott szavak közül, melyekben van 'a' betű, azokban hány darab 'e' betű van!

In [42]:
szavak = ["kiskutya", "nagyeger", "szekesfehervar", "kiseger"]
db = 0
for szo in szavak:
    if "a" in szo:
        for i in range(len(szo)):
            if szo[i] == "e":
                db += 1
print db
6

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 [43]:
szavak = ["kiskutya", "nagyeger", "szekesfehervar", "kiseger"]
db = 0
for szo in szavak:
    if "a" in szo:
        db += szo.count("e")
print db
6
In [ ]: