M = [[1, 2], [3, 4]]
Tömb egy elemét így érhetjük el:
print(M[0], M[0][1])
# 3x2x2-es tömb
M = [[[1, 2], [3, 4]], [[5, 6], [7, 8]], [[0, 9], [0, 0]]]
M[2][0][1]
Írjunk olyan függvényt, mely kiír egy 2D tömböt táblázatszerűen ilyesmi formában:
1 2
3 4
def tomb_kiir(M):
for i in range(len(M)):
for j in range(len(M[i])):
print(M[i][j], end='\t') # TAB karakter
print()
Vigyázzunk, M[i, j]
az M[i][j]
helyett itt nem működik!
tomb_kiir([[1, 2, 3, 3.5], [4, 5, 6, 6.5], [7, 8, 9, 9.5]])
Törzsvásárlói kedvezményt szeretnénk adni a vásárlóinknak. Adott a nevük (egyedi, string) és az eddigi vásárlásaik végösszege (egyenként). Minden ügyfélhez egy lista tartozik, melynek első eleme a személy neve, a második egy lista a vásárlások összegéről, például:
["Anett", [54, 23, 12, 56, 12, 71]]
A kedvezményt a következő módon adnánk:
Összes vásárlás > 200: 10%
Összes vásárlás > 500: 15%
Összes vásárlás > 1000: 20%
Írjuk meg a függvényt, mely megkapja a vásárlók listáját (elemei, mint a fenti "Anett" lista) és visszaad egy listát melyben 2 elemű listák vannak, az első elem a vásárló neve, a második a kedvezménye. Pl:
["Anett", 10]
Hogyan fogjunk neki? Bontsuk részfeladatokra!
Kétféle képpen lehet haladni (wikipedia top-down_bottom-up_design):
# top-down
def kedvezmenyek(vasarlok):
kedvezmenylista = []
for vasarlo in vasarlok:
kedvezmenylista.append(kedvezmeny(vasarlo))
return kedvezmenylista
def kedvezmeny(vasarlo):
nev = vasarlo[0]
osszeg = 0
for vasarlas in vasarlo[1]:
osszeg += vasarlas
return [nev, osszegbol_kedvezmeny(osszeg)]
def osszegbol_kedvezmeny(osszeg):
if osszeg > 1000:
return 20
if osszeg > 500:
return 15
if osszeg > 200:
return 10
return 0
kedvezmenyek([["Anett", [54, 23, 12, 56, 12, 71]],
["Hagrid", [111, 545, 343, 56, 12, 66]],
["Béla", [11, 3, 12, 1, 12, 55]],
["Not_a_wizard", [54, 222, 65, 56, 43, 71]]])
Már megismerkedtünk a karakterláncokkal (sztringekkel) és listákkal, mint összetettebb adatszerkezetekkel. A szám-n-es vagy tuple megadása kerek zárójelek közt vesszőkkel elválasztva, vagy a tuple()
függvénnyel adható meg:
t = (1, 5, 6, 2, 1)
print(t[2])
type(t)
l = [1, 2, 3]
t = tuple(l)
print(t)
A tuple bejárható (iterable) típus, a for
ciklus működik:
for e in t:
print(e, end=" ")
Az elemei nem változtathatók meg (hasonlóan a sztringhez, és ellentétben a listával), azaz értékadás az elemeire nincs megengedve. A rendezett sorozat (tuple) nem változtatható típus (immutable):
t[1] = 4
Bizonyos helyzetekben a zárójel el is hagyható:
# ez is tuple (rendezett sorozat)
x = 2, 3, 4
print(x)
# itt két tuple egyenlősége az x = 2, y = 3 értékadásokkal ekvivalens
x, y = 2, 3
print(x)
print(y)
1-hosszú tuple
nem összetévesztendő a sima zárójellel, ennek érdekében az utolsó (és egyben első) elem után vesszőt rakunk.
print(type((1))) # itt (1) és 1 ugyanazt jelenti, egy egész számot
print(type((1,))) # (1,) egy tuple, melynek egyetlen eleme van
print(type(())) # üres rendezett sorozat
A tuple-k úgy működnek, mint a listák egy kivétellel. A listák elemei változtathatók (mutable), a tuple elemei nem változtathatók (immutable). Egy tuple elemei csak úgy változtathatók meg, ha újra létrehozzuk, hasonlóan a string-ekhez:
s = ("l", "e", "l", "e", "t")
print(s[2])
s = s[:2] + ("h",) + s[3:]
s
for e in s:
print(e, end=' ')
s[2] = "l"
A szótárakat képzelhetjük úgy, mint kulcs-érték párok tárolóit. Egy szótár kulcsa bármilyen megváltoztathatatlan adatszerkezet lehet, akár egyszerű, mint egy egész vagy valós szám, akár egy tuple, vagy egy string, de például a lista nem.
Létrehozhatjuk kapcsos zárójellel { }
vagy a dict()
függvénnyel.
# hány állatod van?
d = {"kutya": 2, "aranyhal": 6}
type(d)
Értékként bármilyen adattípus szerepelhet, nem kell megváltoztathatatlannak lennie. Szótárba új elemet úgy vehetünk fel, ha egy új kulcshoz hozzárendelünk egy értéket:
# egy hím, két nőstény
d["macska"] = [1, 2]
d
Üres szótár is létrehozható:
d = {}
d2 = dict()
d
d2
Egy szótáron belül többféle típusú kulcs is lehet. Szótár konvertálható kételemű listák listájából is:
d = dict([[5, "öt"], ["pi", 3.14159]])
d[(1, 5)] = "tuple"
d["ma"] = "kedd"
print(d)
A szótár kulcsai bejárhatók egy for
ciklussal:
for kulcs in d:
print(kulcs, ":", d[kulcs])
Az előbbi vásárló adatbázis így nézne ki szótárral:
vasarlok = {"Anett": [54, 23, 12, 56, 12, 71],
"Hagrid": [111, 545, 601],
"Béla": [11, 3, 12, 1, 12, 55],
"Not_a_wizard": [54, 222, 165, 56]}
print(vasarlok)
print()
print(vasarlok["Béla"])
Feladat: Írjunk olyan programot, mely minden vásárlónra eltárolja a kedvezményét is.
# szótárral
def kedvezmenyek(vasarlok):
for vasarlo in vasarlok:
vasarlok[vasarlo] = {"v": vasarlok[vasarlo]}
vasarlok[vasarlo]["k"] = kedvezmeny(vasarlok[vasarlo]["v"])
print(vasarlo, vasarlok[vasarlo]["k"])
def kedvezmeny(vasarlo):
osszeg = 0
for vasarlas in vasarlo:
osszeg += vasarlas
return osszegbol_kedvezmeny(osszeg)
def osszegbol_kedvezmeny(osszeg):
if osszeg > 1000:
return 20
if osszeg > 500:
return 15
if osszeg > 200:
return 10
return 0
kedvezmenyek(vasarlok)
vasarlok.keys()
vasarlok.values()
for i in vasarlok.values():
print(i)
sorted(vasarlok)
Hogyan keres gyorsan a kulcsalapján, ha a kulcsok különféle típusúak lehetnek?
Több beépített python függvény és algoritmus is (mint például a dict
) használja a hash()
függvényt, mely minden objektumhoz egy adott bithosszúságú egész számot rendel.
Ezeket a hash-értékeket használja az elemek gyors eléréséhez. Hogy a szótárban a kulcs hash-elhető legyen, nem változhat, ezért a kulcs nem lehet mutable objektum, például lista!
A számítástechnika és a kriptográfia más területein is fontos (mind alkalmazásban, mind elméletben) Haladó adatszerkezetek és algoritmuselemzési technikák, Friedl Katalin.
Mit csinál egy hash:
Ezen felül extra elvárások lehetnek (kriptográfiai hash):
Néhány hash érték, ami lekérhető a hash()
függvénnyel:
print(hash((1, 5)))
print(hash(5), hash(0), hash(False), hash(True))
print(hash((5,)))
print(hash("kutya"))
print(hash("kutyb"))
print(hash("mutya"))
Minden immutable objektum hashelhető (azaz alkalmazható rá a hash()
függvény).
hash([1, 2])
dict
)Bejárható (iterable) az olyan adattípus, mely egyesével vissza tudja adni az összes értékét. Az eddig megismert bejárható adattípusok:
Bejárásra a for
ciklus használható (ezt már előbb láttuk).
Több hasznos művelet alkalmazható egyes bejárható típusokra:
# ismétlés (szótárra nem)
print("kutya "*3)
print((1, 2, 3)*3)
print([1, 2, 3]*3)
# összefűzés, konkatenálás (szótárra nem)
(1, 2) + (2, 4, 6)
Több hasznos beépített függvény van ami egyes bejárható objektumokra alkalmazható.
sum
: egy bejárható objektum elemeinek összege
sorted
: visszaad egy rendezett listát
any
: értéke True, ha van igaz értékű elem, és ha ilyet talál, leáll a kiértékelés
all
: értéke True, ha minden elem értéke igaz
max
: a legnagyobb elemet adja vissza
min
: a legkisebbet
# mind igaz-e (logikai többváltozós "és")
all((False, True, True))
all((0, 1, 1))
# igaz-e valamelyik (logikai többváltozós "vagy")
any((False, True, True))
any((0, 1, 1))
# ezek a hamis értéket adók (ez True lenne, ha volna köztük True)
any((0, 0.0, None, False, [], {}, (), ""))
# Ezek mind True értéket adnak
all((1, 5.2, True, [0], [False], {0:0}, (0,), "a"))
# összeg (számokra van, sztringekre nem)
sum((1, 2, 3))
min((3, 1, 4))
sorted((3, 1, 4))
# az speciális/ékezetes betűket a végére rendezi
sorted("vitorlázó")