Itt vagy: Kezdőlap ‣ Ugorj fejest a Python 3-ba ‣
Nehézségi szint: ♦♦♢♢♢
❝ A csoda minden filozófia alapja, a vizsgálódás a fejlődésük, a tudatlanság a végük. ❞
– Michel de Montaigne
Adattípusok. Tedd félre az első Python programod egy percre, és beszéljünk az adattípusokról. Pythonban minden értéknek van adattípusa, de nem kell deklarálnod a változók adattípusát. Hogy működik ez? Az egyes változóknak eredetileg adott érték alapján a Python meghatározza annak értékét, és nyilvántartja azt.
A Python sok natív adattípussal rendelkezik. A fontosak az alábbiak:
True
vagy False
értékűek lehetnek.
1
és 2
),
lebegőpontosak (1.1
és 1.2
), törtek
(1/2
és 2/3
) vagy akár komplex számok is.
Természetesen ezeknél több típus van. Pythonban minden
objektum, emiatt léteznek modul, függvény,
osztály, metódus, fájl és még lefordított kód
típusok is. Ezek közül néhányat már láttál: a moduloknak nevük
van, a függvényeknek
docstring-jeik
stb. Az osztályokról az
Osztályok és iterátorok fejezetben, a fájlokról
pedig a Fájlok fejezetben fogsz többet megtudni.
A karakterláncok és bájtok elég fontosak – és elég bonyolultak – hogy saját fejezetet kapjanak. Előbb nézzük a többit.
⁂
A logikai értékek igazak vagy hamisak lehetnek. A Python két
konstanssal rendelkezik, amelyek közvetlenül logikai értékekhez
rendelhetők, ezek a True
és
False
. A kifejezések is logikai értékekké
értékelődnek ki. Bizonyos helyeken (mint az if
utasítások), a
Python a kifejezés logikai értékre való kiértékelődését várja. Ezeket a
helyeket logikai kontextusoknak nevezzük. Gyakorlatilag bármely
kifejezést használhatod logikai kontextusban, és a Python megpróbálja
meghatározni annak igazságértékét. A különböző adattípusok különböző
szabályokkal rendelkeznek arra vonatkozóan, hogy logikai kontextusban mely
értékek számítanak igaznak vagy hamisnak. (A fejezet későbbi konkrét
példáinak tükrében majd jobban fogod látni ennek az értelmét.)
Vegyük például ezt a részletet a humansize.py
-ból:
if size < 0:
raise ValueError('a szám nem lehet negatív')
A size egy egész, a 0 egy egész, és a <
egy
numerikus műveleti jel. A size < 0
kifejezés eredménye
mindig logikai érték. Ezt te is kipróbálhatod az interaktív Python
parancsértelmezőben:
>>> size = 1 >>> size < 0 False >>> size = 0 >>> size < 0 False >>> size = -1 >>> size < 0 True
Bizonyos, a Python 2-ből örökölt problémák miatt a logikai értékek
számokként kezelhetők. A True
1
; a
False
0.
>>> True + True 2 >>> True - False 1 >>> True * False 0 >>> True / False Traceback (most recent call last): File "<stdin>", line 1, in <module> ZeroDivisionError: int division or modulo by zero
Jaj, jaj, jaj! Ezt ne csináld. Azt is felejtsd el, hogy szóba hoztam.
⁂
A számok izgalmasak. Olyan sok van belőlük! A Python támogatja mind az egész, mind a lebegőpontos számokat. A megkülönböztetésükhöz nincs típusdeklaráció, a Python a tizedespont jelenléte vagy hiánya alapján tesz különbséget.
>>> type(1) ① <class 'int'> >>> isinstance(1, int) ② True >>> 1 + 1 ③ 2 >>> 1 + 1.0 ④ 2.0 >>> type(2.0) <class 'float'>
type()
függvény használatával ellenőrizheted
bármely érték vagy változó típusát. Ahogy az várható, az 1
egy int
(egész).
isinstance()
függvény használatával
ellenőrizheted, hogy egy érték vagy változó adott típusú-e.
int
és egy másik int
összeadásának
eredménye is egy int
.
int
hozzáadása egy float
-hoz
float
(lebegőpontos) típust eredményez. A Python az
int
értéket float
-típusúvá konvertálja az
összeadás végrehajtásához, majd eredményként egy float
-ot ad
vissza.
Ahogy az imént láttad, egyes operátorok (mint az összeadás) szükség esetén az egészeket lebegőpontos számokká konvertálja. Ezt a típuskényszerítést te is elvégezheted.
>>> float(2) ① 2.0 >>> int(2.0) ② 2 >>> int(2.5) ③ 2 >>> int(-2.5) ④ -2 >>> 1.12345678901234567890 ⑤ 1.1234567890123457 >>> type(1000000000000000) ⑥ <class 'int'>
float()
függvény hívásásával kifejezetten
float
típusúvá konvertálhatsz egy int
-et.
int()
hívásával egy
float
int
-té konvertálható.
int()
függvény csonkol, nem kerekít.
int()
függvény a negatív számokat 0 felé
csonkolja. Ez egy valódi csonkítás függvény, nem pedig alsó egészrész.
☞A Python 2 megkülönbözette az
int
éslong
egészeket. Azint
adattípust asys.maxint
korlátozta, amely platformonként változott, de általában232-1
volt. A Python 3 csak egy egész típussal rendelkezik, amely nagyrészt úgy viselkedik, mint a Python 2 régilong
típusa. A részletekért lásd a PEP 237-et.
A számokkal mindenféle dolgokat csinálhatsz.
>>> 11 / 2 ① 5.5 >>> 11 // 2 ② 5 >>> −11 // 2 ③ −6 >>> 11.0 // 2 ④ 5.0 >>> 11 ** 2 ⑤ 121 >>> 11 % 2 ⑥ 1
/
operátor lebegőpontos osztást végez. Akkor is
float
típusú eredményt ad, ha a számláló és a nevező is
int
.
//
operátor egy fura egészosztást végez. Ha az eredmény
pozitív, akkor veheted úgy, hogy 0 tizdesjegyre csonkít (nem kerekít), de
legyél óvatos vele.
//
operátor
„felfelé” kerekít a legközelebbi egészre. Matematikailag nézve
„lefelé” kerekít, mivel a −6
kisebb, mint
−5
, de becsaphat, ha azt várod, hogy
−5
-re csonkít.
//
operátor nem mindig ad vissza egészet. Ha a
számláló vagy a nevező float
, akkor is a legközelebbi egészre
csonkít, de a tényleges visszatérési érték egy float
lesz.
**
operátor „hatványozást” jelent.
112
= 121
.
%
operátor megadja a maradékot egészosztás után. A
11
osztva 2
-vel 5
, a maradék
1
, így az eredmény 1
.
☞Python 2-ben a
/
operátor általában egészosztást jelentett, de egy speciális utasítás beszúrásával rávehető volt lebegőpontos osztásként való viselkedésre is. Python 3-ban a/
operátor mindig lebegőpontos osztást jelent. A részletekért lásd a PEP 238-at.
A Python nem csak egész és lebegőpontos számokat kezel, de el tudja végezni a középiskolában tanult (és azonnal elfelejtett) elegáns műveleteket is.
>>> import fractions ① >>> x = fractions.Fraction(1, 3) ② >>> x Fraction(1, 3) >>> x * 2 ③ Fraction(2, 3) >>> fractions.Fraction(6, 4) ④ Fraction(3, 2) >>> fractions.Fraction(0, 0) ⑤ Traceback (most recent call last): File "<stdin>", line 1, in <module> File "fractions.py", line 96, in __new__ raise ZeroDivisionError('Fraction(%s, 0)' % numerator) ZeroDivisionError: Fraction(0, 0)
fractions
modult.
Fraction
objektumot,
és add át a számlálót és nevezőt.
Fraction
objektumot adnak vissza. 2 * (1/3) = (2/3)
Fraction
objektum automatikusan egyszerűsíti a
törteket. (6/4) = (3/2)
Pythonban alapszintű trigonometriai számításokat is végezhetsz.
>>> import math >>> math.pi ① 3.1415926535897931 >>> math.sin(math.pi / 2) ② 1.0 >>> math.tan(math.pi / 4) ③ 0.99999999999999989
math
modul rendelkezik egy π konstanssal, amely a
kör kerületének és átmérőjének aránya.
math
modul rendelkezik az összes alapszintű
trigonometriai függvénnyel, beleértve a sin()
,
cos()
, tan()
és ezek változatait, mint az
asin()
.
tan(π / 4)
eredményének 1.0
-nak kellene
lennie, nem 0.99999999999999989
-nek.
Logikai kontextusban, például if
utasításokban használhatsz számokat. A nulla értékek hamisak, a
nem-nulla értékek pedig igazak.
>>> def is_it_true(valami): ① ... if valami: ... print("igen, ez igaz") ... else: ... print("nem, ez hamis") ... >>> is_it_true(1) ② igen, ez igaz >>> is_it_true(-1) igen, ez igaz >>> is_it_true(0) nem, ez hamis >>> is_it_true(0.1) ③ igen, ez igaz >>> is_it_true(0.0) nem, ez hamis >>> import fractions >>> is_it_true(fractions.Fraction(1, 2)) ④ igen, ez igaz >>> is_it_true(fractions.Fraction(0, 1)) nem, ez hamis
0.0
hamis. Légy
óvatos ezzel! Ha a legkisebb kerekítési hiba is előfordul (nem lehetetlen,
mint azt az előző szakaszban láttad), akkor a Python a
0.0000000000001
-et fogja tesztelni a 0 helyett, és
True
értéket ad.
Fraction(0,
n)
hamis minden n értékre. Minden más tört igaz.
⁂
A list a Python igásló adattípusa. Amikor azt mondom, „lista”, azt gondolhatod: „olyan tömb, amelyet előre kell deklarálni, csak azonos típusú elemeket tartalmazhat, stb”. Ne gondold. A listák ennél sokkal menőbbek.
☞A lista Pythonban olyan, mint egy tömb Perl 5-ben. Perl 5-ben a tömböket tároló változók a
@
karakterrel kezdődnek, Pythonban a változók tetszőleges nevűek lehetnek, és a Python maga tartja nyilván az adattípust.
☞Python listái sokkal többet tudnak, mint a Java tömbök (de úgy is használhatod, ha ez minden vágyad). Jobban hasonlít az
ArrayList
osztályhoz, amely tetszőleges objektumokat képes tárolni, és dinamikusan tud bővülni az új elemek hozzáadásakor.
A listák létrehozása egyszerű: tedd szögletes zárójelbe az értékek vesszőkkel elválasztott listáját.
>>> a_list = ['a', 'b', 'mpilgrim', 'z', 'example'] ① >>> a_list ['a', 'b', 'mpilgrim', 'z', 'example'] >>> a_list[0] ② 'a' >>> a_list[4] ③ 'example' >>> a_list[-1] ④ 'example' >>> a_list[-3] ⑤ 'mpilgrim'
a_list[0]
.
a_list[4]
, mert a
listaelemek indexelése mindig nullától kezdődik.
a_list[-1]
.
a_list[-n] == a_list[len(a_list) - n]
.
Ebben a listában a_list[-3] == a_list[5 - 3] == a_list[2]
.
Miután definiáltál egy listát, bármely részét megkaphatod új listaként. Ezt a lista szeletelésének nevezzük.
>>> a_list ['a', 'b', 'mpilgrim', 'z', 'example'] >>> a_list[1:3] ① ['b', 'mpilgrim'] >>> a_list[1:-1] ② ['b', 'mpilgrim', 'z'] >>> a_list[0:3] ③ ['a', 'b', 'mpilgrim'] >>> a_list[:3] ④ ['a', 'b', 'mpilgrim'] >>> a_list[3:] ⑤ ['z', 'example'] >>> a_list[:] ⑥ ['a', 'b', 'mpilgrim', 'z', 'example']
a_list[1]
) kezdve a második szeletindexig (ebben az esetben
a_list[3]
), de azt nem beleértve.
a_list[0:3]
a lista első három elemét adja vissza az a_list[0]
elemtől az
a_list[3]
elemig, de az utóbbit már nem tartalmazza.
a_list[:3]
ugyanaz, mint az
a_list[0:3]
mert a kezdő 0-t a Python feltételezi.
a_list[3:]
ugyanaz, mint az
a_list[3:5]
, mert ez a lista öt elemű. Van itt egy kellemes
szimmetria. Ebben az öt elemű listában az a_list[:3]
visszaadja az első 3 elemet, az a_list[3:]
pedig az utolsó
két elemet. Tulajdonképpen az a_list[:n]
mindig az első n elemet adja vissza, az
a_list[n:]
pedig a többit, a lista hosszától
függetlenül.
a_list[:]
a lista teljes
lemásolására használható.
Négy módon lehet elemeket felvenni a listába.
>>> a_list = ['a'] >>> a_list = a_list + [2.0, 3] ① >>> a_list ② ['a', 2.0, 3] >>> a_list.append(True) ③ >>> a_list ['a', 2.0, 3, True] >>> a_list.extend(['négy', 'Ω']) ④ >>> a_list ['a', 2.0, 3, True, 'négy', 'Ω'] >>> a_list.insert(0, 'Ω') ⑤ >>> a_list ['Ω', 'a', 2.0, 3, True, 'négy', 'Ω']
+
operátor összefűzi a listákat, ezzel létrehozva egy
új listát. Egy lista tetszőleges számú elemet tartalmazhat; nincs
méretkorlát (az elérhető memórián kívül). Ha azonban a memóriahasználat
fontos szempont, akkor tudnod kell, hogy a listaösszefűzés egy második
listát hoz létre a memóriában. Ebben az esetben az új lista azonnal
hozzárendelődik a meglévő a_list változóhoz. Így ez a kódsor
igazából egy kétlépéses folyamat – összefűzés, majd
hozzárendelés – amely (ideiglenesen) rengeteg memóriát tud
használni, ha nagy listákkal dolgozol.
append()
metódus egy elemet ad a lista végéhez. (Most
már négy különböző adattípus van a listában!)
extend()
metódus egy argumentumot vár, amely egy lista, és az
argumentum minden elemét hozzáfűzi az eredeti listához.
insert()
metódus egyetlen elemet szúr be a listába. Az
első argumentum a lista első olyan elemének indexe, amely ki lesz mozdítva
a pozícójából. A lista elemeinek nem kell egyedieknek lenniük, most például
két külön 'Ω'
értékű elem van a listában: az első elem
(a_list[0]
) és az utolsó elem (a_list[6]
).
☞Az
a_list.insert(0, érték)
olyan, mint azunshift()
függvény Perlben. Felvesz egy elemet a lista elejére, és az összes többi elem indexe megnő eggyel, hogy helyet csináljanak az új elemnek.
Nézzük meg közelebbről az append()
és extend()
közti különbséget.
>>> a_list = ['a', 'b', 'c'] >>> a_list.extend(['d', 'e', 'f']) ① >>> a_list ['a', 'b', 'c', 'd', 'e', 'f'] >>> len(a_list) ② 6 >>> a_list[-1] 'f' >>> a_list.append(['g', 'h', 'i']) ③ >>> a_list ['a', 'b', 'c', 'd', 'e', 'f', ['g', 'h', 'i']] >>> len(a_list) ④ 7 >>> a_list[-1] ['g', 'h', 'i']
extend()
metódus egyetlen argumentumot vár, amely
mindig egy lista, és ennek a listának minden elemét hozzáfűzi az
a_list listához.
append()
metódus egyetlen argumentumot
vár, amely tetszőleges adattípusú lehet. Itt az append()
metódust egy három elemű listával hívod meg.
>>> a_list = ['a', 'b', 'új', 'mpilgrim', 'új'] >>> a_list.count('új') ① 2 >>> 'új' in a_list ② True >>> 'c' in a_list False >>> a_list.index('mpilgrim') ③ 3 >>> a_list.index('új') ④ 2 >>> a_list.index('c') ⑤ Traceback (innermost last): File "<interactive input>", line 1, in ? ValueError: list.index(x): x not in list
count()
metódus visszaadja egy lista
adott értékeinek előfordulásainak számát.
in
operátor kicsit gyorsabb, mint a
count()
metódus. Az in
operátor mindig a
True
vagy False
értéket adja vissza, azt nem
adja meg, hogy az érték hányszor jelenik meg a listában.
in
operátor és a count()
metódus sem adja
meg, hogy az érték hol jelenik meg a listában. Ha szeretnéd
tudni, hogy a listában hol van egy érték, akkor használd
az index()
metódust. A Python alapértelmezésben az egész
listában keres, noha megadhatsz egy elhagyható második argumentumot, a
keresés kezdő indexét, sőt egy elhagyható harmadik argumentumot is, a
keresés befejező indexét (mindkettő nullától kezdődik).
index()
metódus az érték első előfordulását
találja meg a listában. Ebben az esetben az 'új'
kétszer
fordul elő a listában, az a_list[2]
és a_list[4]
elemekként, de az index()
metódus csak az első előfordulás
indexét adja vissza.
index()
metódus kivételt dob.
Várjunk csak? Így van: az index()
metódus kivételt dob, ha
nem találja az értéket a listában. Ez látványosan eltér a legtöbb
nyelvtől, amelyek általában érvénytelen indexet (mint a -1
)
adnak vissza. Noha ez elsőre idegesítőnek tűnhet, szerintem idővel
értékelni fogod. Ez azt jelenti, hogy a programod a probléma forrásánál
fog összeomlani, nem pedig később furán és némán. Ne feledd, a -1
egy érvényes listaindex. Ha az
index()
metódus -1
-et adna vissza, az jónéhány,
nem túl vidám hibakeresési körhöz vezethetne!
A listák képesek automatikusan bővülni és szűkülni. A bővülés részt már láttad. Az elemek listából való eltávolítására is számos különböző módszer van.
>>> a_list = ['a', 'b', 'új', 'mpilgrim', 'új'] >>> a_list[1] 'b' >>> del a_list[1] ① >>> a_list ['a', 'új', 'mpilgrim', 'új'] >>> a_list[1] ② 'új'
del
utasítás használható.
1
-es index elérése az 1
-es index törlése
után nem eredményez hibát. Minden, a törölt elem utáni elem
eltolja a helyzeti indexét az elem törlésével létrejött „lyuk
kitöltéséhez”.
Nem ismered a helyzeti indexet? Nem gond, az elemeket érték alapján is eltávolíthatod.
>>> a_list.remove('új') ① >>> a_list ['a', 'mpilgrim', 'új'] >>> a_list.remove('új') ② >>> a_list ['a', 'mpilgrim'] >>> a_list.remove('új') Traceback (most recent call last): File "<stdin>", line 1, in <module> ValueError: list.remove(x): x not in list
remove()
metódussal is
eltávolíthatsz. A remove()
metódus egy értéket vár,
és eltávolítja az adott érték első előfordulását a listából. Ismét, a
törölt elem mögötti elemek helyzeti indexe csökkenni fog, hogy
„kitöltsék a lyukat”. A listákban soha nincsenek lyukak.
remove()
metódust annyiszor hívhatod, ahányszor csak
akarod, de kivételt fog dobni, ha a listában nem szereplő értéket próbálsz
eltávolítani.
Egy másik érdekes metódus a pop()
. A pop()
metódus egy újabb lehetőség elemek
eltávolítására egy listából, de van benne egy csavar.
>>> a_list = ['a', 'b', 'új', 'mpilgrim'] >>> a_list.pop() ① 'mpilgrim' >>> a_list ['a', 'b', 'új'] >>> a_list.pop(1) ② 'b' >>> a_list ['a', 'új'] >>> a_list.pop() 'új' >>> a_list.pop() 'a' >>> a_list.pop() ③ Traceback (most recent call last): File "<stdin>", line 1, in <module> IndexError: pop from empty list
pop()
listametódus
eltávolítja a utolsó elemet a listából, és visszaadja az eltávolított
értéket.
pop()
metódusnak. Ekkor
eltávolítja az elemet, az azt követő összes elemet elmozgatja „a
lyuk kitöltéséhez”, és visszaadja az eltávolított értéket.
pop()
üres listán való hívásakor kivételt dob.
☞A
pop()
listametódus argumentumok nélküli hívása olyan, mint apop()
függvény Perlben. Eltávolítja a lista utolsó elemét, és visszaadja az eltávolított elem értékét. A Perl egy másik,shift()
nevű függvénnyel is rendelkezik, amely eltávolítja az első elemet, és visszaadja az értékét. Pythonban ez egyenlő aza_list.pop(0)
hívással.
Logikai kontextusban, például if
utasításokban használhatsz listákat is.
>>> def is_it_true(valami): ... if valami: ... print("igen, ez igaz") ... else: ... print("nem, ez hamis") ... >>> is_it_true([]) ① nem, ez hamis >>> is_it_true(['a']) ② igen, ez igaz >>> is_it_true([False]) ③ igen, ez igaz
⁂
A tuple egy megváltoztathatatlan lista. A tuple létrehozása után semmilyen módon sem módosítható.
>>> a_tuple = ("a", "b", "mpilgrim", "z", "példa") ① >>> a_tuple ('a', 'b', 'mpilgrim', 'z', 'példa') >>> a_tuple[0] ② 'a' >>> a_tuple[-1] ③ 'példa' >>> a_tuple[1:3] ④ ('b', 'mpilgrim')
a_tuple[0]
.
A tuple és a lista közti legnagyobb különbség, hogy a tuple nem
módosítható. Technikai kifejezéssel élve a tuple-ök
megváltoztathatatlanok. Gyakorlati szempontból nincsenek olyan
metódusaik, amelyek lehetővé tennék a módosításukat. A listák rendelkeznek
olyan metódusokkal, mint az append()
, extend()
,
insert()
, remove()
és pop()
. A
tuple-ök ezek egyikével sem. A tuple szeletelhető (mert az egy új tuple-t
hoz létre), és ellenőrizheted, hogy egy tuple tartalmaz-e egy adott
értéket (mert ez nem változtatja meg a tuple-t), és ez minden.
# az előző példa folytatása >>> a_tuple ('a', 'b', 'mpilgrim', 'z', 'példa') >>> a_tuple.append("új") ① Traceback (innermost last): File "<interactive input>", line 1, in ? AttributeError: 'tuple' object has no attribute 'append' >>> a_tuple.remove("z") ② Traceback (innermost last): File "<interactive input>", line 1, in ? AttributeError: 'tuple' object has no attribute 'remove' >>> a_tuple.index("példa") ③ 4 >>> "z" in a_tuple ④ True
append()
vagy extend()
metódussal.
remove()
vagy pop()
metódussal.
in
operátort is egy elem meglétének
ellenőrzésére a tuple-ben.
Akkor mire jók a tuple-ök?
assert
utasításod lenne, amely jelzi,
hogy ezek az adatok konstansak, és külön elhatározás (és egy bizonyos
függvény) szükséges a felülbírálásához.
☞A tuple-ök átalakíthatók listákká, és fordítva. A beépített
tuple()
függvény egy listát vár, és visszaad egy tuple-t ugyanazokkal az elemekkel, alist()
függvény pedig egy tuple-t vár és listát ad vissza. Gyakorlatilag atuple()
befagyasztja a listát, alist()
pedig kiolvasztja.
Logikai kontextusban, például if
utasításokban használhatsz tuple-öket is.
>>> def is_it_true(valami): ... if valami: ... print("igen, ez igaz") ... else: ... print("nem, ez hamis") ... >>> is_it_true(()) ① nem, ez hamis >>> is_it_true(('a', 'b')) ② igen, ez igaz >>> is_it_true((False,)) ③ igen, ez igaz >>> type((False)) ④ <class 'bool'> >>> type((False,)) <class 'tuple'>
Itt egy menő programozási trükk: Pythonban egy tuple használatával egyszerre több értéket is hozzárendelhetsz változókhoz.
>>> v = ('a', 2, True)
>>> (x, y, z) = v ①
>>> x
'a'
>>> y
2
>>> z
True
(x, y, z)
pedig
egy három változót tartalmazó tuple. Az egymáshoz rendelésükkel a
v értékei a változókhoz lesznek rendelve, a megadott
sorrendben.
Ezt sok mindenre fel lehet használni. Tegyük fel, hogy neveket
szeretnél rendelni egy értéktartományhoz. A beépített range()
függvényt többváltozós értékadásban az egymást követő értékek
hozzárendeléséhez használhatod.
>>> (HÉTFŐ, KEDD, SZERDA, CSÜTÖRTÖK, PÉNTEK, SZOMBAT, VASÁRNAP) = range(7) ① >>> HÉTFŐ ② 0 >>> KEDD 1 >>> VASÁRNAP 6
range()
függvény egészek sorozatát állítja
elő. (Technikailag a range()
függvény egy iterátort ad vissza, nem pedig listát vagy
tuple-t, de erről a különbségről később fogsz tanulni.) A
HÉTFŐ, KEDD, SZERDA,
CSÜTÖRTÖK, PÉNTEK, SZOMBAT és
VASÁRNAP a definiált változók. (Ez a példa a
calendar
modulból származik, amely naptárakat ír ki, mint a
cal
nevű UNIX program. A calendar
modul egész konstansokat definiál a hét napjaihoz.)
1
és így tovább.
A több érték hozzárendelése használatával olyan függvényeket építhetsz,
amelyek több értéket adnak vissza, egyszerűen az értékeket tartalmazó
tuple visszaadásával. A hívó ezt kezelheti egyetlen tuple-öként vagy
értékeket rendelhet az egyes változókhoz. Sok szabványos Python
függvénytár így tesz, beleértve az os
modult, amelyet a következő fejezetben fogsz megismerni.
⁂
A halmaz egyedi értékek rendezetlen „kupaca”. Egy halmaz tetszőleges megváltoztathatatlan adattípusú értékeket tartalmazhat. Ha van két halmazod, akkor végrehajthatsz rajtuk általános halmazműveleteket, mint az unió, metszet és különbség.
Kezdjük az elején. Egy halmazt létrehozni könnyű.
>>> a_set = {1} ① >>> a_set {1} >>> type(a_set) ② <class 'set'> >>> a_set = {1, 2} ③ >>> a_set {1, 2}
{}
) közé.
Halmazt egy listából is létrehozhatsz.
>>> a_list = ['a', 'b', 'mpilgrim', True, False, 42] >>> a_set = set(a_list) ① >>> a_set ② {'a', False, 'b', True, 'mpilgrim', 42} >>> a_list ③ ['a', 'b', 'mpilgrim', True, False, 42]
set()
függvényt. (Azok a pedánsok, akik ismerik a halmazok megvalósítását, rá fognak mutatni, hogy ez valójában nem függvényhívás, hanem egy osztály példányosítása. Megígérem, hogy a könyv hátralévő részeiben meg fogod ismerni a különbséget. Egyelőre elég annyi, hogy a set()
függvényszerűen működik, és egy halmazt ad vissza.)
Még nincsenek értékeid? Nem gond. Létrehozhatsz üres halmazt is.
>>> a_set = set() ① >>> a_set ② set() >>> type(a_set) ③ <class 'set'> >>> len(a_set) ④ 0 >>> not_sure = {} ⑤ >>> type(not_sure) <class 'dict'>
set()
függvényt argumentumok nélkül.
{}
? Az egy üres szótárat jelölne, nem pedig egy üres halmazt. A szótárakkal a fejezet későbbi részében fogsz megismerkedni.
Meglévő halmazhoz két különböző módon adhatsz értékeket: az add()
és az update()
metódusokkal.
>>> a_set = {1, 2} >>> a_set.add(4) ① >>> a_set {1, 2, 4} >>> len(a_set) ② 3 >>> a_set.add(1) ③ >>> a_set {1, 2, 4} >>> len(a_set) ④ 3
add()
metódus egyetlen argumentumot vár, amely tetszőleges adattípusú lehet, és az adott értéket hozzáadja a halmazhoz.
>>> a_set = {1, 2, 3} >>> a_set {1, 2, 3} >>> a_set.update({2, 4, 6}) ① >>> a_set ② {1, 2, 3, 4, 6} >>> a_set.update({3, 6, 9}, {1, 2, 3, 5, 8, 13}) ③ >>> a_set {1, 2, 3, 4, 5, 6, 8, 9, 13} >>> a_set.update([10, 20, 30]) ④ >>> a_set {1, 2, 3, 4, 5, 6, 8, 9, 10, 13, 20, 30}
update()
metódus egy argumentumot vár, egy halmazt, és minden elemét hozzáadja az eredeti halmazhoz. Olyan, mintha a halmaz minden egyes elemére meghívtad volna az add()
metódust.
update()
metódust ténylegesen tetszőleges számú argumentummal hívhatod meg. Két halmazzal hívva az update()
metódus az egyes halmazok összes elemét hozzáadja az eredeti halmazhoz (a többször szereplő értékek eldobásával).
update()
metódus számos különböző adattípus objektumait képes kezelni, beleértve a listákat is. Egy listával hívva az update()
metódus a lista összes elemét hozzáadja az eredeti halmazhoz.
Három módon távolíthatsz el egyedi értékeket a halmazból. Az első kettő, a discard()
és remove()
között egy apró különbség van.
>>> a_set = {1, 3, 6, 10, 15, 21, 28, 36, 45} >>> a_set {1, 3, 36, 6, 10, 45, 15, 21, 28} >>> a_set.discard(10) ① >>> a_set {1, 3, 36, 6, 45, 15, 21, 28} >>> a_set.discard(10) ② >>> a_set {1, 3, 36, 6, 45, 15, 21, 28} >>> a_set.remove(21) ③ >>> a_set {1, 3, 36, 6, 45, 15, 28} >>> a_set.remove(21) ④ Traceback (most recent call last): File "<stdin>", line 1, in <module> KeyError: 21
discard()
metódus egyetlen értéket vár argumentumként, és eltávolítja azt az értéket a halmazból.
discard()
metódust a halmazban nem létező értékkel hívod, akkor nem csinál semmi. Nem fog kivételt dobni, csak nem csinál semmit.
discard()
metódus is egyetlen értéket vár argumentumként, és szintén eltávolítja azt az értéket a halmazból.
remove()
metódus egy KeyError
kivételt dob.
A listákhoz hasonlóan a halmazoknak is van pop()
metódusuk.
>>> a_set = {1, 3, 6, 10, 15, 21, 28, 36, 45} >>> a_set.pop() ① 1 >>> a_set.pop() 3 >>> a_set.pop() 36 >>> a_set {6, 10, 45, 15, 21, 28} >>> a_set.clear() ② >>> a_set set() >>> a_set.pop() ③ Traceback (most recent call last): File "<stdin>", line 1, in <module> KeyError: 'pop from an empty set'
pop()
metódus egyetlen értéket távolít el a halmazból, és visszaadja az értéket. Mivel azonban a halmazok rendezetlenek, nincs „utolsó” értékük, így nincs lehetőség az eltávolított érték befolyásolására. Teljesen tetszőleges.
clear()
metódus minden értéket eltávolít a halmazból, és egy üres halmazt hagy. Ez egyenértékű az a_set = set()
hívással, amely egy új üres halmazt hoz létre, és az a_set változó korábbi értékét felülírja.
KeyError
kivételt dob.
A Python set
típusa számos általános halmazműveletet támogat.
>>> a_set = {2, 4, 5, 9, 12, 21, 30, 51, 76, 127, 195} >>> 30 in a_set ① True >>> 31 in a_set False >>> b_set = {1, 2, 3, 5, 6, 8, 9, 12, 15, 17, 18, 21} >>> a_set.union(b_set) ② {1, 2, 195, 4, 5, 6, 8, 12, 76, 15, 17, 18, 3, 21, 30, 51, 9, 127} >>> a_set.intersection(b_set) ③ {9, 2, 12, 5, 21} >>> a_set.difference(b_set) ④ {195, 4, 76, 51, 30, 127} >>> a_set.symmetric_difference(b_set) ⑤ {1, 3, 4, 6, 8, 76, 15, 17, 18, 195, 127, 30, 51}
in
operátort. Ez ugyanúgy működik, mint a listák esetén.
union()
metódus egy új halmazt ad vissza, amely tartalmazza az összes, valamelyik halmazban jelen lévő elemet.
intersection()
metódus egy új halmazt ad vissza, amely tartalmazza az összes, mindkét halmazban jelen lévő elemet.
difference()
metódus egy új halmazt ad vissza, amely tartalmazza az a_set halmazban jelen lévő, de a b_set halmazban jelen nem lévő elemet.
symmetric_difference()
metódus egy új halmazt ad vissza, amely tartalmazza az összes, pontosan egy halmazban jelen lévő elemet.
Ezen metódusok közül három szimmetrikus.
# az előző példa folytatása >>> b_set.symmetric_difference(a_set) ① {3, 1, 195, 4, 6, 8, 76, 15, 17, 18, 51, 30, 127} >>> b_set.symmetric_difference(a_set) == a_set.symmetric_difference(b_set) ② True >>> b_set.union(a_set) == a_set.union(b_set) ③ True >>> b_set.intersection(a_set) == a_set.intersection(b_set) ④ True >>> b_set.difference(a_set) == a_set.difference(b_set) ⑤ False
Végül néhány, a halmazokkal kapcsolatos kérdés.
>>> a_set = {1, 2, 3} >>> b_set = {1, 2, 3, 4} >>> a_set.issubset(b_set) ① True >>> b_set.issuperset(a_set) ② True >>> a_set.add(5) ③ >>> a_set.issubset(b_set) False >>> b_set.issuperset(a_set) False
False
értéket ad vissza.
Logikai kontextusban, például if
utasításokban használhatsz halmazokat is.
>>> def is_it_true(valami): ... if valami: ... print("igen, ez igaz") ... else: ... print("nem, ez hamis") ... >>> is_it_true(set()) ① nem, ez hamis >>> is_it_true({'a'}) ② igen, ez igaz >>> is_it_true({False}) ③ igen, ez igaz
⁂
A szótár kulcs-érték párok rendezetlen halmaza. Amikor a szótárhoz hozzáadsz egy kulcsot, akkor a kulcs értékét is meg kell adnod. (Az érték később bármikor módosítható.) A Python szótárak az ismert kulcsú értékek lekérésére vannak optimalizálva, de ez nem működik fordítva.
☞A szótár Pythonban olyan, mint egy hash Perl 5-ben. Perl 5-ben a hasheket tároló változók a
%
karakterrel kezdődnek. Pythonban a változók tetszőleges nevűek lehetnek, és a Python maga tartja nyilván az adattípust.
Egy szótárat létrehozni könnyű. A szintaxis hasonló a halmazokhoz, de értékek helyett kulcs-érték párok vannak. A meglévő szótárból az értékeket a kulcsuk alapján keresheted ki.
>>> a_dict = {'kiszolgáló': 'db.diveintopython3.org', 'adatbázis': 'mysql'} ① >>> a_dict {'server': 'db.diveintopython3.org', 'database': 'mysql'} >>> a_dict['kiszolgáló'] ② 'db.diveintopython3.org' >>> a_dict['adatbázis'] ③ 'mysql' >>> a_dict['db.diveintopython3.org'] ④ Traceback (most recent call last): File "<stdin>", line 1, in <module> KeyError: 'db.diveintopython3.org'
'kiszolgáló'
egy kulcs, és a hozzá tartozó érték, amelyre a_dict['kiszolgáló']
formában hivatkozhatsz, a'db.diveintopython3.org'
.
'adatbázis'
egy kulcs, és a hozzá tartozó érték, amelyre a_dict['adatbázis']
formában hivatkozhatsz, a'mysql'
.
a_dict['kiszolgáló']
visszatérési értéke'db.diveintopython3.org'
, de az a_dict['db.diveintopython3.org']
kivételt dob, mert a 'db.diveintopython3.org'
nem egy kulcs.
A szótáraknak nincs előre meghatározott méretkorlátjuk. Bármikor hozzáadhatsz új kulcs-érték párokat egy szótárhoz, vagy módosíthatod egy meglévő kulcs értékét. Az előző példa folyatása:
>>> a_dict {'kiszolgáló': 'db.diveintopython3.org', 'adatbázis': 'mysql'} >>> a_dict['database'] = 'blog' ① >>> a_dict {'kiszolgáló': 'db.diveintopython3.org', 'adatbázis': 'blog'} >>> a_dict['felhasználó'] = 'mark' ② >>> a_dict ③ {'kiszolgáló': 'db.diveintopython3.org', 'felhasználó': 'mark', 'adatbázis': 'blog'} >>> a_dict['felhasználó'] = 'dora' ④ >>> a_dict {'kiszolgáló': 'db.diveintopython3.org', 'felhasználó': 'dora', 'adatbázis': 'blog'} >>> a_dict['Felhasználó'] = 'mark' ⑤ >>> a_dict {'Felhasználó': 'mark', 'kiszolgáló': 'db.diveintopython3.org', 'felhasználó': 'dora', 'adatbázis': 'blog'}
'felhasználó'
, érték: 'mark'
) középen jelenik meg. Tulajdonképpen az csak véletlen volt, hogy az első példában az elemek sorrendben jelentek meg, ugyanannyira véletlen, hogy most nem sorrendben jelennek meg.
felhasználó
kulcs értékét "mark"-ra? Nem! Nézd meg jobban a kulcsot – az egy nagy F a "Felhasználó"-ban. A szótárkulcsok megkülönböztetik a kis- és nagybetűket, így ez az utasítás egy új kulcs-érték párt hoz létre, nem pedig egy meglévőt ír felül. Számodra hasonlónak tűnhetnek, de Python szempontjából teljesen különbözők.
A szótárak nem csupán karakterláncokat tárolhatnak. A szótárértékek tetszőleges adattípusúak lehetnek, beleértve az egész és logikai értékeket, tetszőleges objektumokat vagy akár más szótárakat is. Ezen túl egy szótáron belül az értékeknek nem kell azonos típusúaknak lenniük, szükség szerint keverhetők. A használható szótárkulcstípusok köre korlátozottabb, de a kulcsok lehetnek karakterláncok, egészek és még néhány egyéb típusúak. Egy szótáron belül a kulcsok adattípusai szintén keverhetők.
Tulajdonképpen már láttál egy nem-karakterlánc kulcsokat és értékeket tartalmazó szótárat az első Python programodban.
SUFFIXES = {1000: ['KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'],
1024: ['KiB', 'MiB', 'GiB', 'TiB', 'PiB', 'EiB', 'ZiB', 'YiB']}
Szedjük ezt szét az interaktív parancsértelmezőben.
>>> SUFFIXES = {1000: ['KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'], ... 1024: ['KiB', 'MiB', 'GiB', 'TiB', 'PiB', 'EiB', 'ZiB', 'YiB']} >>> len(SUFFIXES) ① 2 >>> 1000 in SUFFIXES ② True >>> SUFFIXES[1000] ③ ['KB', 'MB', 'GB', 'TB', 'PB', 'EB', 'ZB', 'YB'] >>> SUFFIXES[1024] ④ ['KiB', 'MiB', 'GiB', 'TiB', 'PiB', 'EiB', 'ZiB', 'YiB'] >>> SUFFIXES[1000][3] ⑤ 'TB'
len()
függvény megadja a kulcsok számát a szótárban.
in
operátorral tesztelheted, hogy egy adott kulcs szerepel-e a szótárban.
1000
egy kulcs a SUFFIXES
szótárban, az értéke egy nyolc elemet (pontosabban nyolc karakterláncot) tartalmazó lista.
1024
is egy kulcs a SUFFIXES
szótárba, az értéke szintén egy nyolc elemet tartalmazó lista.
SUFFIXES[1000]
egy lista, az elemeit a 0-tól kezdődő indexük alapján elérheted.
Logikai kontextusban, például if
utasításokban használhatsz szótárakat is.
>>> def is_it_true(valami): ... if valami: ... print("igen, ez igaz") ... else: ... print("nem, ez hamis") ... >>> is_it_true({}) ① nem, ez hamis >>> is_it_true({'a': 1}) ② igen, ez igaz
⁂
None
A None
egy speciális konstans Pythonban. Ez egy null érték. A None
nem ugyanaz, mint a False
. A None
nem 0. A None
nem egy üres karakterlánc. A None
összehasonlítása bármivel, ami nem None
mindig False
értéket ad.
A None
az egyetlen nullérték. Saját adattípussal rendelkezik (NoneType
). A None
bármely változóhoz hozzárendelhető, de nem hozhatsz létre más NoneType
objektumokat. Minden változó, amely értéke None
, egyenlő egymással.
>>> type(None) <class 'NoneType'> >>> None == False False >>> None == 0 False >>> None == '' False >>> None == None True >>> x = None >>> x == None True >>> y = None >>> x == y True
None
logikai kontextusbanA logikai kontextusokban a None
hamis és a not None
igaz.
>>> def is_it_true(valami): ... if valami: ... print("igen, ez igaz") ... else: ... print("nem, ez hamis") ... >>> is_it_true(None) nem, ez hamis >>> is_it_true(not None) igen, ez igaz
⁂
fractions
modul
math
modul
© 2001–11 Mark Pilgrim