Elemi programozási tételek középiskolásoknak, a Python 3 nyelvet alapul véve Koós Antal, (CC BY-NC-SA 4.0) 2016
Ajánlott olvasmányok: A Python 3 dokumentációja angolul: docs.python.org
Tartalom
A „Python a gépben” c. könyv: www.interkonyv.hu/konyvek/koos_antal_python_a_gepben
FOGALMAK ....................................................................................................2 KERESÉSI TÉTEL.............................................................................................5 MEGSZÁMLÁLÁSI TÉTEL............................................................................7 ÖSSZEGZÉSI TÉTEL.......................................................................................9 A MINIMUM KIVÁLASZTÁSÁNAK TÉTELE ......................................10 KIVÁLOGATÁSI TÉTEL..............................................................................12 RENDEZÉS BESZÚRÁSSAL........................................................................14 BUBORÉKRENDEZÉS...................................................................................16 RENDEZÉS A MINIMUM KIVÁLASZTÁSÁVAL..................................17 RENDEZÉS A PYTHON 3-BAN.................................................................18 HALMAZMŰVELETEK A PYTHON 3-BAN..........................................19 BINÁRIS KERESÉS.........................................................................................22
Érettségi feladatok megoldásai: sites.google.com/site/eutlantis/erettsegi
Koós Antal
Elemi programozási tételek, Python 3
FOGALMAK Az általános programozási elvek tanításánál célszerűnek tűnik egy programnyelv specialitásaiban nem elmélyedve olyan ismereteket átadni, amelyek bármelyik másik nyelvben is hasznosíthatóak. Ilyen téma a tömbök és azok indexeléssel történő kezelése, ami egyaránt alkalmazható az alacsony és a magas szintű programozási nyelvekben. A magasabb szintű nyelvekből mostanra már igen sok létezik, s egyre újabbak megalkotására történnek próbálkozások. Ezekben a nyelvekben közös, hogy a tömbökön túlmenően, a nyelvhez tartozóan, olyan előre definiált objektumtípusokkal bírnak, amelyek a tömbökhöz képest sokkal több funkcionalitást hordoznak és így gyorsabb fejlesztést tesznek lehetővé, illetve megkönnyíthetik a logikai tervezést. Ezen objektumtípusoknak egy része (valószínűleg) az összes magas szintű nyelvben megtalálható, és bár más-más nevet viselnek, az alapvető tulajdonságaik azonosak, például ilyenek a szótárak, asszociatív tömbök, listák, karakterláncok, halmazok, készletek, sorok, vermek stb. Az ilyen objektumokkal kapcsolatos, az egyik nyelvben megszerzett összes ismeret ugyan nem vihető át egy az egybe egy másik nyelv tanulási folyamatába, de megkönnyítheti azt az alapvető tulajdonságok általánosításával. Ebben az írásban a Python 3 nyelvet alapul véve néhány példát mutatunk a középiskolában tanított elemi programozási elvek megfogalmazására, de nem célunk az összes tétel ismertetése. Az algoritmusok megadásánál nem valamilyen pszeudokódot használunk, hanem magát a Python 3-t, s ehhez előzetesen megadjuk bizonyos fogalmak és nyelvi elemek rövid magyarázatát. Kezdjük az objektumokkal: Iterálható objektum: Olyan objektum, amelyből más objektumokat tudunk kinyerni. A kiolvasott objektumokat a továbbiakban elemnek fogjuk nevezni. Az elemeket az objektumon történő iterálással, más kifejezéssel az objektum bejárásával egymásután sorban elérhetjük. Az iterálható objektumok sokfélék lehetnek: van amelyik 2/22
Koós Antal
Elemi programozási tételek, Python 3
eleve tartalmazza az összes elemét, és van, amelyik csak a bejárás folyamán állítja azokat elő; némelyik indexelhető, némelyik nem; egyesekben módosíthatóak az elemek, másokban nem; és olyanok is léteznek, amelyek a bejárás után „kiüresednek” stb. A bejáráshoz mindig előállítható egy ún. iterátor objektum, de speciális esetekben alkalmazható az indexelés vagy az ún. kulcs szerinti hivatkozás is. Példák: listák, bájt-tömbök, karakterláncok, sokaságok, szótárak, generátorobjektumok stb. Indexelhető objektum: Az ilyen objektum elemeit a természetes számok sorozatának 0-val induló és eggyel növekedő tagjaival párosíthatjuk, s az ezekre történő hivatkozással (indexeléssel) az elemeket el is érhetjük. Ha egy objektum indexelhető, akkor iterálható is, de egy iterálható objektum nem feltétlen indexelhető, az indexelhetőség egy erősebb megszorítás. Példák: listák, karakterláncok (string), sokaságok (tuple-k), bájt-tömbök (bytes) stb. Ellenpéldák: készletek, szótárak, egész számok stb. Leképező (mapping) típusú objektum: Ezen objektum elemeit kulcs-érték párok alkotják. Egy elemhez tartozó értéket a kulcs indexszerű megadásával érhetünk el. Kulcs nagyon sokféle objektum lehet, például számok, karakterláncok stb., és ezek keverten is alkalmazhatók. Ezek az objektumok a kulcsok szerint iterálhatók. (Ha egy konkrét szótár kulcsai egymásután következő egész számok, 0-val kezdődően, és csak ezek, akkor úgy tűnhet, hogy ez a szótár indexelhető, de az elemek elérésének belső mechanizmusa ekkor is eltér a "valódi" indexeléstől.) Példa: szótár. Ellenpélda: listák, készletek stb.
3/22
Koós Antal
Elemi programozási tételek, Python 3
Az algoritmusok leírásában felhasznált nyelvi elemek: • A blokkokat a sorok behúzásával jelöljük. • A for és while szerkezetekhez tartozhat egy else ág is, amely akkor hajtódik végre, ha a ciklustörzsből nem történt kilépés a break utasítással. • enumerate(bejárható): Az iterálható bejárható objektum elemeit szolgáltatja egymásután, és minden elemhez ad egy sorszámot is, a sorszámozás 0-val kezdődik. Ha az objektum indexelhető, akkor a sorszám megegyezik az indexszel. (A sorszám és az index kapcsolatának megvilágítására vegyük azt a példát, amikor egy hivatalban a szolgáltatást igénybe venni kívánó személyeknek sorszámot kell húzniuk, és akkor mehetnek az ügyintéző pultjához, ha az információs tábla megjeleníti azt. Addig azonban tetszés szerint leülhetnek a szabad székekre, illetve ácsoroghatnak a helyiségben bárhol. A sorszám tehát a személyek érkezési (korábbi-későbbi) idejének a leképezése, de nem ad semmilyen felvilágosítást a személyek elhelyezkedéséről. Ám, ha ez a hivatal egy „szigorú intézmény”, akkor megkövetelheti, hogy az emberek rögtön álljanak sorba amint megérkeznek, s ekkor a sorszám már a helyet is meghatározza, „indexeli”. Az enumerate() az elemek kiolvasásának idejét képezi le a sorszámra. Egy indexelhető objektum esetén az elemek az indexüknek megfelelően, 0-tól kezdve egyenként kerülnek felsorolásra, azaz a sorszám meg fog egyezni az indexszel.) • len(bejárható): A bejárható objektum elemszámát adja meg. • range(n): 0-tól n-1 -ig szolgáltatja az egész számokat egymásután. A range(m,n,l) kifejezésben az egész számok sorozata m-től indul, n-1-ig tart, és l a növekményük. A range(m,n) esetén a lépésköz 1 lesz. • True, False: Az igaz és a hamis értékek. A következőkben a „tulajdonság(elem)/kifejezés(elem)” kifejezéseket ott szerepeltetjük, ahol vagy egy előzetesen definiált függvényt alkalmazhatunk, amelynek az „elem” az argumentuma, vagy ahová egy az „elemet” tartalmazó kifejezést közvetlenül beírhatunk. 4/22
Koós Antal
Elemi programozási tételek, Python 3
KERESÉSI TÉTEL Egy iterálható objektumban keresünk egy adott tulajdonságú elemet. Nem szükséges, hogy az objektum indexelhető vagy módosítható legyen. A kimenet hamis lesz, ha az objektum nem tartalmaz a kívánt tulajdonságú elemből. Ha tartalmaz, akkor egy többelemű sokaság (tuple) az eredmény, amelynek első eleme az igaz értékű True, a többit pedig a feladat természetének megfelelően választhatjuk, például a második lehet maga a keresett elem, a harmadik pedig annak sorszáma, illetve indexe, ha az objektum indexelhető. Az algoritmus első változatában nem vagyunk kíváncsiak a sorszámra (indexre), a másodikban igen:
for elem in bejárható: if tulajdonság(elem): kimenet= True,elem break else: kimenet= False
for sorszám,elem in enumerate(bejárható): if tulajdonság(elem): kimenet= True,elem,sorszám break else: kimenet= False
Ha nincs szükségünk magára az elemre, csak arra az információra, hogy van-e ilyen tulajdonságú az objektumban, akkor elegendő csak a True-False értékeket használnunk kimenetként (döntési tétel). Ha bizonyosak vagyunk benne, hogy a keresett tulajdonságú elemből legalább egy van az objektumban, akkor elhagyhatjuk az „else” blokkot és a kimenetből a True értéket (kiválasztási tétel). (Megjegyzés: Amennyiben valamely programnyelvben nem lehetséges egynél több értéket adni egy változónak vagy egy függvény visszatérési értékének, akkor ott egy olyan adatstruktúra címét kell megadni, amit feltölthetünk a kívánt értékekkel.) 5/22
Koós Antal
Elemi programozási tételek, Python 3
Az alábbiakban bemutatjuk a fenti algoritmus indexeléses változatát is, amely nyilván csak indexelhető objektumokkal használható:
for index in range(len(bejárható)): if tulajdonság(bejárható[index]): kimenet= True,bejárható[index],index break else: kimenet= False
Példák:
# lista: iterálható, indexelhető, módosítható bejárható= [1,2,3,4,5,6,16]
# befagyasztott készlet: # iterálható, nem indexelhető, nem módosítható bejárható= frozenset({1,3,42,2.7,5,42,42,3.14})
for elem in bejárható: if elem%3==1 and elem>5: kimenet= True,elem break else: kimenet= False
for sorszám,elem in enumerate(bejárható): if elem>3 and elem<4: kimenet= True,elem,sorszám break else: kimenet= False
print(kimenet)
print(kimenet)
Amennyiben egy elemnek csak az objektumbeli meglétére vagyunk kíváncsiak, akkor a Pythonban elegendő az in operátor használata (for nélkül), amire példákat a halmazműveletekről szóló fejezetben találhatunk. 6/22
Koós Antal
Elemi programozási tételek, Python 3
MEGSZÁMLÁLÁSI TÉTEL A keresési tételnél egy iterálható objektumban kerestünk egy adott tulajdonságú elemet, s ha találtunk ilyent, akkor megálltunk. Most megszámláljuk ezeket, a kimenet a darabszám lesz. Nem szükséges, hogy az objektum indexelhető vagy módosítható legyen, de megadjuk a „hagyományos” indexelős változatát is az algoritmusnak.
darab=0 for elem in bejárható: if tulajdonság(elem): darab=darab+1
darab=0 for index in range(len(bejárható)): if tulajdonság(bejárható[index]): darab=darab+1
Példák:
bejárható= [ 2,4,6,5,7,8]
bejárható= ["alma","körte","meggy","alma","alma"]
párosak=0 for elem in bejárható: if elem%2==0: párosak+=1
darab=0 for elem in bejárható: if elem=="alma": darab+=1
print(párosak)
print(darab)
7/22
Koós Antal
Elemi programozási tételek, Python 3
Megjegyzés: Az ún. asszociatív tömbök segítségével könnyen megtehetjük, hogy egy bejárható objektumban nem csak az egy adott tulajdonsággal bíró elemek számát határozzuk meg, hanem több tulajdonság alapján végzünk számlálást. Nem kell előre megbecsülnünk a változatok számát, azaz nem szükséges előzetesen helyet foglalni a darabszámokat nyilvántartó változóknak. A Pythonban ezt a szótár (dictionary) objektummal kivitelezhetjük. Nézzük a példát:
bejárható= ["alma","körte","meggy",1,2,3,"alma","alma",-10] darabok=dict() for elem in bejárható: if type(elem)== int: darabok["egész_számok"]= darabok.get("egész_számok",0)+1 else: darabok[elem]= darabok.get(elem,0)+1 print(darabok)
A kimenet: { 'meggy': 1, 'körte': 1, 'alma': 3, 'egész_számok': 4 } A get() metódus az első argumentumként megadott kulcshoz tartozó értéket olvassa ki a szótárból, de ha még nincs ilyen kulcs, akkor a második argumentum kerül a kifejezésbe helyettesítő értékként. Listák esetében a count(elem) metódussal egyszerűen megkaphatjuk a megadott elem darabszámát.
8/22
Koós Antal
Elemi programozási tételek, Python 3
ÖSSZEGZÉSI TÉTEL Egy bejárható és csak számokat tartalmazó objektum elemeiből származtatott értékek összegét képezzük. Nem szükséges, hogy az objektum indexelhető vagy módosítható legyen. Megadjuk az indexelős változatot is.
eredmény=0 for elem in bejárható: eredmény=eredmény+kifejezés(elem)
eredmény=0 for index in range(len(bejárható)): eredmény= eredmény+kifejezés(bejárható[index])
Példa: bejárható= [1,2,3,4] eredmény=0 for elem in bejárható: eredmény+= elem*elem print(eredmény)
# eredmény+= elem print(sum(bejárható))
Megjegyzés: Amikor csupán az elemek összegére vagyunk kíváncsiak, használhatjuk a Python sum() függvényét bármely bejárható objektumon. 9/22
Koós Antal
Elemi programozási tételek, Python 3
A MINIMUM KIVÁLASZTÁSÁNAK TÉTELE Egy bejárható, nem üres objektum elemei közül kiválasztjuk a legkisebbet. Nem szükséges, hogy az elemek számok legyenek, elegendő ha az elemek között értelmezhető a kisebb-nagyobb viszony. Például két karakterlánc közül kisebb az, amelyik az ábécé szerinti sorba rendezésnél előbbre kerül (lexikografikus összehasonlítás).
minimum= kifejezés(bejárható) for elem in bejárható: if elem<minimum: minimum= elem
minimum=bejárható[0] for index in range(1,len(bejárható)): if bejárható[index]<minimum: minimum= bejárható[index]
minimum,index= bejárható[0],0 for index in range(1,len(bejárható)): if bejárható[index]<minimum: minimum,index= bejárható[index],index
Megadtuk az algoritmus indexeléses verzióit is, amelyek közül a második nem csak a minimumot, hanem annak indexét is előállítja. Az indexelésnek most megvan az az előnye, hogy a minimum nevű változónak könnyű kezdeti értéket adni. A nem indexelős algoritmus általánosabban van megfogalmazva, de ha az objektum indexelhető, akkor a kifejezés(bejárható) szerkezet lecserélhető az indexeléses változatban szereplő kezdeti értékadásra. Kezdőértékként mindig megadhatunk egy „elég nagy” véges értékű konstanst is, ami biztosan nagyobb lesz a bejárható objektum bármely eleménél. Sok nyelvben eleve rendelkezésre áll olyan 10/22
Koós Antal
Elemi programozási tételek, Python 3
konstans vagy objektum, amely a műveletekben úgy viselkedik, mintha végtelen nagy lenne, a Pythonban ezt így állíthatjuk elő: float('inf') (a legkisebbhez pedig a float('-inf') szükséges). A Pythonban a kezdeti értékadást a nem indexelhető esetben egy ún. iterátor objektummal is elvégezhetjük: a minimum=next(iter(bejárható)) kifejezés a felsorolás első elemét állítja be. Ha nincs szükségünk a minimális elem indexére, akkor a Pythonban a standard min() függvény mindent elvégez helyettünk. (Természetesen a min() alkalmazása után, a minimum ismeretében, egy második bejárás során az indexet, sőt az összes minimális értékkel bíró elem indexét is meghatározhatjuk). A függvénynek bemeneti értékként megadhatjuk, ha szükséges, hogy a bejárható objektum elemeihez hogyan kell képezni az összehasonlításhoz szükséges értékeket (kulcsokat). Ezt egy ún. kulcsfüggvény megadásával tehetjük meg, amire az alábbiakban példát mutatunk. (A maximum megkeresésének végiggondolását az olvasóra bízzuk.)
bejárható= [10,1,5,0.2,3] print(min(bejárható))
#-------------------------diákok=[ ("János",17,4.9),("Etel",18,4.2),("Viola",19,4.1) ] def hasonlítandó(elem): név,kor,átlag= elem return átlag #return elem[2] #return név
A kimenet az alábbi lesz:
0.2 ('Viola', 19, 4.1)
print(min(diákok,key=hasonlítandó))
11/22
Koós Antal
Elemi programozási tételek, Python 3
KIVÁLOGATÁSI TÉTEL Adott egy bejárható Abej nevű objektum és egy meghatározott tulajdonság, az Abej-ben lévő és az adott tulajdonsággal bíró elemekről másolatot kell készíteni egy másik bejárható Bbej objektumba. Nem szükséges hogy az Abej indexelhető legyen, de megadjuk az algoritmus indexelős változatát is. Az sem szükséges, hogy az Abej módosítható legyen, de a Bbej-nek értelemszerűen annak kell lennie. A nem indexelős, általánosabb érvényű változatban a Bbej egy lista típusú objektum lesz, amelyhez az append() metódussal lehet elemeket hozzáfüggeszteni. Az algoritmus indexelős változatában a feltöltendő objektum létrehozását nem mutatjuk be, csak az írási indexének adunk kezdőértéket. Bbej=[] for elem in Abej: if tulajdonság(elem): Bbej.append(elem)
bindex=0 for index in range(len(Abej)): if tulajdonság(Abej[index]): Bbej[bindex]= Abej[index] bindex=bindex+1
Példák: # Abej: indexelhető lista Abej=[0,1,1,2,3,5,8] Bbej=[] # Bbej: indexelhető lista for elem in Abej: if elem*elem>20: Bbej.append(elem)
A kimenet: [5, 8]
print(Bbej)
12/22
Koós Antal
Elemi programozási tételek, Python 3
# Abej egy set: nem indexelhető Abej= {"alma","körte","meggy","kiwi"} Bbej=[] for elem in Abej: if len(elem)==4: Bbej.append(elem)
A kimenet: ['kiwi', 'alma']
print(Bbej)
Abej= ["alma","körte","alma","meggy","kiwi"] # Az írandó objektum nem indexelhető, de nincs is rá szükség: Bbej=set() for elem in Abej: if len(elem)==4: Bbej.add(elem)
A kimenet: {'kiwi', 'alma'}
print(Bbej)
A fenti utolsó példában az írandó objektumot listáról készletre cseréltük, az append() metódust pedig a megfelelő add()-ra. Az alábbi példa bemutatja, hogy a Python ún. listaépítő (list comprehension) szerkezetével milyen tömören lehet a kiválogatást kódolni (ugyanez készletépítés lesz, ha a [] helyett {} használunk): Abej=[0,1,1,2,3,5,8] Bbej= [ elem for elem in Abej if elem*elem>20 ] print(Bbej)
13/22
Koós Antal
Elemi programozási tételek, Python 3
RENDEZÉS BESZÚRÁSSAL Egy módosítható és indexelhető objektum elemeinek a sorrendjét szeretnénk megváltoztatni úgy, hogy a legkisebb elem a 0-s indexű helyre kerüljön, majd azt kövesse a második legkisebb stb. Amint a minimum kiválasztásának tételénél megemlítésre került, itt sem szükséges, hogy az elemek számok legyenek, elegendő ha az elemek között értelmezhető a kisebb-nagyobb viszony. Az alábbi algoritmusokban az objektumot A-val jelöltük:
N=len(A) for k in range(1,N): T= A[k] i=k-1 while i>=0 and T
N=len(A) for k in range(1,N): i=k-1 while i>=0 and A[i+1]
A[i+1]=T
Tekintsük előbb a bal oldali eljárást. Az algoritmusban az objektumot két tartományra bontva képzeljük el: az „alsó” tartományban, a 0-s indextől kezdve az elemek „valameddig” már rendezve vannak, a „felső” tartomány még rendezetlen. Ekkor vesszük a „felső” tartomány „legalsó” elemét, aminek az értéke bármilyen nagy vagy kicsi is lehet, és megnézzük, hogy az alsó rendezett tartományba hová szúrhatjuk be, hogy ott a rendezettség fenn is maradjon. A beszúrás helye a már rendezett tartományt két részre bontja: az alsó részt változatlanul hagyjuk, utána beírjuk a beszúrandó elemet, de előtte a felső részt „feltoljuk” egy pozícióval, hogy az a 14/22
Koós Antal
Elemi programozási tételek, Python 3
beszúrandó elem eredeti helyét, ami még a rendezetlen tartományban van, magába foglalja. Így a felső rendezetlen tartomány eggyel kevesebb elemmel fog bírni, és az eljárást ismételve az egész objektum rendezett lesz. A külső (k) ciklus az 1-es indexel kezdődik, mert úgy vesszük, hogy a 0-s indexű elem önmagában már egy rendezett tartományt képez. A beszúrás helye fölötti rendezett rész eltolását nem egyben végezzük, hanem egyesével, mert ezt megtehetjük lépésenként, amikor a beillesztendő elem új helyét keressük, és így nem kell kétszer bejárni ezt a részt. A jobb oldali algoritmusban nem emeljük ki a beszúrandó elemet (például egy T változóba), hanem a lépésenkénti összehasonlítás során megcseréljük a nála nagyobbakkal, azaz az eljárást akár egyfajta cserélő algoritmusnak is nevezhetjük. Nézzünk néhány példát: a=[10,3,8,1,2,8,5,-1] b=["xyz","efgh","abc","ab","Ab"] c=[] def rendez(A): N=len(A) for k in range(1,N): i=k-1 while i>=0 and A[i+1]
A kimenet:
[-1, 1, 2, 3, 5, 8, 8, 10] ['Ab', 'ab', 'abc', 'efgh', 'xyz'] []
rendez(a) rendez(b) rendez(c) print("\n",a,"\n",b,"\n",c)
15/22
Koós Antal
Elemi programozási tételek, Python 3
BUBORÉKRENDEZÉS Egy módosítható és indexelhető objektumról van szó. A buborékos rendezés egy nem túl hatékony cserélő algoritmus, de az elve érdekes. Minden lépésben egy elemet a helyére viszünk, az első lépésben a legnagyobb elemet, a másodikban a második legnagyobbat stb. Így a k-adik lépés után az objektum legnagyobb első k eleme már a helyén lesz, és ha N elem van, akkor a külső ciklust N-szer kell végrehajtani. A belső ciklusban mindig a 0-ás elemtől indulunk (technikailag a range az i=1-től kezdődik, de utána A[i-1]-re történik hivatkozás), amelyet összehasonlítunk a következővel, és ha az előbbi a nagyobb, akkor megcseréljük őket, majd ezt folytatjuk az 1-es és a 2-es indexűekkel stb. Így mindig a nagyobb elem száll felfelé, mint egy buborék. Az első lépésben, k=0 és még egyetlen elem sincs a helyén, most „buborékoltatjuk” az elsőt, a második (k=1) lépésben már a legnagyobb elem az objektum legtetején van és az összehasonlításokkal meg lehet előtte állni, a k-adik lépésben pedig csak az első N-k elemmel kell foglalkoznunk.
N=len(A) for k in range(0,N): for i in range(1,N-k): if A[i-1]>A[i]: A[i],A[i-1]= A[i-1],A[i]
16/22
Koós Antal
Elemi programozási tételek, Python 3
RENDEZÉS A MINIMUM KIVÁLASZTÁSÁVAL Egy módosítható és indexelhető objektumot fogunk rendezni. Az első lépésben kiválasztjuk a legkisebb elemet és az objektum 0-s indexű pozíciójába írjuk, a második lépésben a második legkisebbet keressük meg és írjuk az 1-es indexű helyre stb. A k-adik lépésben már az első k darab legkisebb elem a helyén van, elegendő a következő legkisebbet a k+1-es és magasabb indexűek között keresni. Figyeljük meg, hogy a belső ciklusban nem végzünk elemcserét, amivel hatékonyabbá válik az eljárás:
N=len(A) for k in range(0,N-1): minindex=k for i in range(k+1,N): if A[i]
17/22
Koós Antal
Elemi programozási tételek, Python 3
RENDEZÉS A PYTHON 3-BAN A Python legrugalmasabban használható objektumának, a listának van egy sort() metódusa, amivel helyben lehetséges a rendezést végrehajtani. A felhasználásához nem szükséges tudnunk (bár utána lehet nézni), hogy ez milyen algoritmus szerint működik, és az eljárás mibenléte érdektelen (amennyiben a tudásvágyunk kielégítésétől eltekintünk), ha a megoldandó feladatokkal számunkra megfelelő idő alatt végez. Az előzőekben megadott rendezési algoritmusokat csak olyan objektumokra tudjuk alkalmazni, amelyek egyidejűleg módosíthatóak és indexelhetőek. Más típusú, de bejárható objektumok elemeit egy külön listában tudjuk rendezetten előállítani. Egyrészt készíthetünk az objektumból egy listát, amit a sort()-tal már tudunk kezelni, vagy a sorted() alapfüggvényt is alkalmazhatjuk. Mindkét esetben megadhatunk egy kulcsfüggvényt, illetve fordított sorrendet is kérhetünk. Íme néhány példa: diákok=frozenset( { ("Etel",18,4.2),("János",17,4.9),("Viola",19,4.1)} ) def hasonlítandó(elem): név,kor,átlag= elem return átlag #return név ldiák= list(diákok) ldiák.sort(key=hasonlítandó) # (key=hasonlítandó, reverse=True) print(ldiák) ldiák2= sorted(diákok, key=hasonlítandó, reverse=True) print(ldiák2) A kimenet: [('Viola', 19, 4.1), ('Etel', 18, 4.2), ('János', 17, 4.9)] [('János', 17, 4.9), ('Etel', 18, 4.2), ('Viola', 19, 4.1)]
18/22
Koós Antal
Elemi programozási tételek, Python 3
HALMAZMŰVELETEK A PYTHON 3-BAN A Python azon objektumaira, amelyek más objektumokat, azaz elemeket tartalmaznak, halmazokként is tekinthetünk. Érdemes megjegyezni, hogy ezek közül a készlet típusú (set) objektumoknak az az alapvető tulajdonsága, hogy nincs bennük két azonos értékű elem, a hozzájuk adott duplikátumokat „szó nélkül” kidobják. Az alábbiakban bemutatjuk néhány halmazművelet kivitelezését:
A= [ 1, 2, 99,99,99, 3,3, 5,5, "Python" ] # lista B= ( "Python", 99, 5,5,5, 42,42 ) # sokaság C= "Python 3" # karakterlánc D= { "Python", 99, 5, 42, "3" } # készlet print("Lista:",A,"\nSokaság:",B,"\nKarakterlánc:",C,"\nKészlet:",D,"\n")
# Tartalmazás: print("Tartalmazás:") van= "t" in C print(van) print( 99 in A ) print( "Python" in B ) print( "Python" in C ) print( 2016 in A ) print() # Két lista uniója: U1= A+list(B) print(" Unió listaként:",U1) U2= set(U1) # U2= set(A+list(B)) print(" Unió készletként:",U2) print()
19/22
Koós Antal
Elemi programozási tételek, Python 3
# Metszetek, amelyek az ismétlődésekben különbözhetnek: M1= [ elem for elem in A if elem in B ] print(" Metszet ismétlődésekkel(1) listában:",M1) M2= [ elem for elem in B if elem in A ] print(" Metszet ismétlődésekkel(2) listában:",M2) M3= { elem for elem in A if elem in B } print(" Metszet ismétlődések nélkül, készletben:",M3) M4= list(M3) print(" Metszet ismétlődések nélküli listában:",M4) print() # Különbségek, amelyek az ismétlődésekben eltérhetnek: S= [ elem for elem in A if elem not in B ] print(" A-B ismétlődésekkel listában:",S) S= [ elem for elem in B if elem not in A ] print(" B-A ismétlődésekkel listában:",S) print() # Készletek uniója készletként: U= set(A) | set(B) | D print(" Készletek uniója készletként:",U) # Készletek metszete készletként: U= set(A) & set(B) & D print(" Készletek metszete készletként",U)
20/22
Koós Antal
Elemi programozási tételek, Python 3 A kimenet: Lista: [1, 2, 99, 99, 99, 3, 3, 5, 5, 'Python'] Sokaság: ('Python', 99, 5, 5, 5, 42, 42) Karakterlánc: Python 3 Készlet: {'Python', '3', 99, 42, 5} Tartalmazás: True True True True False Unió listaként: [1, 2, 99, 99, 99, 3, 3, 5, 5, 'Python', 'Python', 99, 5, 5, 5, 42, 42] Unió készletként: {1, 2, 3, 5, 'Python', 42, 99} Metszet Metszet Metszet Metszet
ismétlődésekkel(1), listában: [99, 99, 99, 5, 5, 'Python'] ismétlődésekkel(2), listában: ['Python', 99, 5, 5, 5] ismétlődések nélkül, készletben: {'Python', 99, 5} ismétlődések nélküli listában: ['Python', 99, 5]
A-B ismétlődésekkel, listában: [1, 2, 3, 3] B-A ismétlődésekkel, listában: [42, 42] Készletek uniója készletként: {1, 2, 3, 5, 'Python', 42, '3', 99} Készletek metszete készletként {'Python', 99, 5}
A készletekkel még további halmazműveletek is végezhetők (például szimmetrikus differencia, részhalmaz tartalmazása stb.), de ezek bemutatására itt nem térünk ki.
21/22
Koós Antal
Elemi programozási tételek, Python 3
BINÁRIS KERESÉS A keresést jelentősen meggyorsítja, ha az objektum, amiben keresünk rendezve van. Az objektumnak indexelhetőnek kell lennie, maga a keresés nem igényli a módosíthatóságot, de az előzetes rendezés igen. Az eljárás végén az elem megtalálása esetén a True értéket és az elem indexét fogjuk megkapni, az elem hiányában pedig a False értéket. Az első lépésben az objektum „közepén” lévő elemet vetjük össze a keresett elemmel, és ha egyeznek, akkor az algoritmus véget ér, egyébként az összehasonlítástól függően a keresés alsó vagy felső indexének határát módosítjuk és ezen szűkített tartományban megismételjük az eljárást stb. Az algoritmus a legrosszabb esetben is log2N lépésben véget ér, ahol N az elemek száma. N=len(A) # Csak rendezett objektumon működik jól! alsó,felső=0,N-1 while alsó<=felső: k=(felső+alsó)//2 # a // egész számú hányadost ad if keresett < A[k]: felső=k-1 elif keresett > A[k]: alsó=k+1 else: kimenet=True,k break else: kimenet=False
22/22