Ügyességi játékok programozása
Pythonnal és Pygame-mel

Chapter 7: Bevezetés a listákhoz

7.1 Adattípusok

Videó: Bevezetés a listákhoz

Ezidáig ebben a könyvben négyféle adatot ismertünk meg:

A pythonnal megnézhetjük, hogy milyen típusú az értékünk, ha lekérjük azt a type függvénnyel. Kétségkívül ez a függvény nem túl hasznos azokhoz a dolgokhoz, amiket ebben a könyben tanulunk, de kiválóan alkalmas az adattípusok jobb megértéséhez. Gépeld be az alábbit az IDLE shell-be. (Most ne hozz létre új ablakoot, hogy programként kezeld, ez most nem kell.)

type(3)
type(3.145)
type("Hi there")
type(True)
Output:
>>> type(3)
<class 'int'>

>>> type(3.145)
<class 'float'>

>>> type("Hi there")
<class 'str'>

>>> type(True)
<class 'bool'>

Lehetőség van még arra, hogy a type függvényt használjuk ahhoz, hogy lássuk, hogy egy változóban miféle adat is van.

x = 3
type(x)

A két új adattípus, amit ebben a fejezetben bemutatunk, az a Lista és a Vektor lesz (list, és tuple angolul - a ford.). Próbáld meg futtatni az alábbi parancsot az interaktív python shell-ben, és nézd meg, hogy mi is történik:

type(  (2,3,4,5) )
type(  [2,3,4,5] )

7.2 Munka a listákkal

Készítettél már bevásárlói listát, cselekvési listát, bakancslistát, de hogyan kell ezt elkészíteni a számítógépen?

fig.grocery_list
Figure 7.1: Még a számítógépek is használnak listát

Próbáld ki ezeket a példákat az IDLE parancssorában. Készíts listát, és jelenítsd meg. Szóval az alábbiakat próbáld ki:

>>> x = [1,2]
>>> print(x)
[1, 2]

Egy darab elemet is megjeleníthetsz, egy sorban:

>>> print(x[0])
1

Ez a szám a listaelem helye, amit indexnek hívunk. Jegyezd meg, hogy a listában az elemek a nulladik hellyel kezdődnek. Szóval, egy 10 elemmel rendelkező listában nincs elem a [10]-s helyen. Csak [0]-tól [9]-ig. Nagyon zavaró bír lenni, hogy 10 elemmel rendelkező listát készítesz, és nincs tízes számú elem. De a legtöbb számítógépes nyelv nullával kezdi a számolást és nem eggyel.

Gondolj úgy a listára, mint egy jégtálcára, ami számokat tartalmaz, ahogyan azt az alábbi ábra 7.2 mutatja. Az értékeket a jégtálca kis rekeszeiben tárolja, és a számok a tálca oldalára vannak festve, amik nullával kezdődnek, és minden rekeszhez tartozik egy.

Emlékezz rá, hogy kétféle szám fontos, amikor listákkal dolgozunk: a pozíció és az érték. A pozíció, vagy más néven index, azt mutatha meg, hogy hol van az érték. Az érték pedig az az adott szám, amit ezen a helyen tárolnak. Amikor egy számsorral dolgozol, bizonyosodj meg felőle, hogy ismered a számsorban az elemek helyét vagy az értéket.

Könnyű értéket adni egy adott helynek, de nehezebb megtalálni egy érték helyét. A 16-dik fejezet írja le azt, hogyan találd meg a helyét, egy adott értéknek.

fig.ice_cube_tray
Figure 7.2: A listák olyanok, mint egy jégtálca

Egy program képes arra, hogy értéket adjon egy listaelemnek. A lenti példa az első elemhez, ami a nullás helyen található rendeli a 22-t, mint számot.

>>> x[0] = 22
>>> print(x)
[22, 2]

Továbbá a program képes vektort létrehozni (tuple). Ez az adattípus ugyanúgy működik, mint a lista, mindössze két kivételt eltekintve. Először is, zárójellel hozzuk létre, és nem szögletes zárójellel. Másodszor pedig, nem lehetséges megváltoztatni, ha már egyszer létrehoztuk. Lásd alább:

>>> x = (1,2)
>>> print(x)
(1, 2)
>>> print(x[0])
1
>>> x[0] = 22
Traceback (most recent call last):
  File "<pyshell#18>", line 1, in <module>
    x[0] = 22
TypeError: 'tuple' object does not support item assignment
>>>

Ahogy az látható volt a fenti kód kimenetén, nem rendelhetünk új elemet egy vektor eleméhez. Miért jó ez a behatárolás? Először is, a számítógép gyorsabban fut, ha tudja, hogy az érték nem változik. Másodszor, némely listát mi nem szeretnénk megváltoztatni, mint amilyen a vörös szín RGG kódja. A vörös szín nem változik, ezért az állandó vektor a legjobb választás.

Egy számsor (array) az elemek listája. Ez egy fontos adatstruktúra a számítástudományban. A lista adattípus a Pythonban nagyon hasonlít egy számsor adatstruktúrájához.

7.3 Iteráció egy listában

Videó: Iteráció egy listában

Ha arra van szükségünk, hogy iteráljuk a lista minden elemét, ha például szeretnénk kiíratni, akkor azt kétféle for ciklussal tehetjük meg.

Az első eljárásban iteráljuk az össze elemet, egy for-each ciklusban. Ez a ciklustípus összegyűjti az elemeket és egyszer végrehajtódik minden elemen. Képez egy másolatot minden elemről és eltárolja egy változóban a végrehajtás során.

A parancs formája:
for elem változója in lista neve:

Itt van néhány példa:

my_list = [101,20,10,50,60]
for item in my_list:
    print( item )
Output:
101
20
10
50
60

A programok képesek szöveget is tárolni:

my_list = ["Spoon", "Fork", "Knife"]
for item in my_list:
    print(item)
Output:
Spoon
Knife
Fork

A lista tartalmazhat másik listát is. Így iterálható minden elem a főlistából, de nem az al-listából.

my_list = [ [2,3], [4,3], [6,7] ]
for item in my_list:
    print(item)
Output:
[2,3]
[4,3]
[6,7]

A másik módja annak, hogy iteráljunk egy listából az az, hogy használunk egy index változót és közvetlen hozzáférünk a listához, ahelyett, hogy lemásolnánk minden elemét. Az index változó használatához, a programunk számolni fog nullától a lista elemeinek számáig. Ha például tíz elemünk van, akkor nullától kilencig.

A lista hosszát megtudhatjuk a len függvénnyel. Ezt kombinálhatjuk a range függvénnyel, ami segít a ciklusunkat a teljes listán átfutni.

my_list = [101,20,10,50,60]
for i in range( len(my_list) ):
    print( my_list[i] )
Output:
101
20
10
50
60

Ez az eljárás már sokkal összetettebb, de sokkal hatékonyabb is. Mivel közvetlenül a lista elemeivel dolgozunk, nem csak a másolatokkal, a lista módosítható. A for-each megoldás nem ad rá lehetőséget, hogy módosítsuk az eredeti listánkat.

7.4 Elem hozzáadása listához

Adhatunk új elemeket egy listához (vektorhoz nem), amihez az append parancsot használjuk. Például:

my_list = [2,4,5,6]
print(my_list)
my_list.append(9)
print(my_list)
Output:
[2,4,5,6]
[2,4,5,6,9]
Videó: Elem hozzáadása listához

Széljegyzet: Nagyon fontos megértenünk azt, ahogyan egy lista implementálva van. Például, ha a listát úgy implementáljuk, mint egy számsor adattípust, akkor számot adni ehhez a listához kicsit olyan, mint mikor egy új tojást adunk a tojástartónkhoz, ami tele van. Ekkor kell készítenünk egy tartót, de most már 13 férőhellyel. Át kell pakolnunk a 12 tojást a régiből, és hozzáadnunk az utolsót. Ezután eldobjuk a régi tartót. Ez az, ami a kulisszák mögött folyik egy függvényben, ezt szokták a programozók elfelejteni, és hagyják a számítógépre, hogy megcsinálja. Ennél sokkal hatékonyabb, ha már az elején szólunk a számítógépnek, hogy mekkora tojástartót készítsen, hogy legyen elég hely minden tojásnak. Szerencsére, a Python nem implementál listát számsor adattípusként. De fontos, hogy odafigyeljünk arra, hogy a következő szemeszter adatstruktúrái már elmagyarázzák azt, ahogyan ezek működnek.

Ahhoz, hogy listát készítsünk egy vázlatból, szükséges egy üres listát készíteni, és azután az append föggvénnyel feltölteni. Ez a példa a felhasználó által megadott adatok alapján készít egy listát:

my_list = [] # Üres lista
for i in range(5):
    userInput = input( "Enter an integer: ")
    userInput = int( userInput )
    my_list.append(userInput)
    print(my_list)
Output:
Enter an integer: 4
[4]
Enter an integer: 5
[4, 5]
Enter an integer: 3
[4, 5, 3]
Enter an integer: 1
[4, 5, 3, 1]
Enter an integer: 8
[4, 5, 3, 1, 8]

Ha egy programnak szükséges van arra, hogy számsort képezzen megadott hossz alapján, hasonló értékekkel, akkor egy egyszerű trükkel megtehetjük ezt:

# Készítsünk vektorlistát, 100 nullával.
my_list = [0] * 100

7.5 List amódosítása vagy összegzése

Videó: Lista szummázása

Egy sorozat összegét megadni szokványos művelet, itt van a hogyanja:

# A szummázandó vektor másolása
myArray = [5,76,8,5,3,3,56,5,23]

# A kezdeti összegünk nulla
arrayTotal = 0

# Ciklus indul nullától felfelé, az elemek számáig
# a vektorban:
for i in range( len(myArray) ):
	# Add element 0, next 1, then 2, etc.
	arrayTotal += myArray[i]

# Az eredmény kiíratása
print( arrayTotal )

Hasonló dolog történik, amikor a for ciklust iterálja a számsort, ahelyett, hogy egy adott skálán számolnánk:

# A szummázandó vektor másolása
myArray = [5,76,8,5,3,3,56,5,23]

# A kezdeti összegünk nulla
arrayTotal = 0

# Ciklusunk átfut a vektorlistán, aztán minden elemet lemásol
# a változó által megadott elembe (item változóba).
for item in myArray:
	# Az elemek összegzése
	arrayTotal += item

# Eredmény kiíratása
print( arrayTotal )

Egy számsorban a számok megváltoztathatóak a for ciklussal:

# Másoljuk le a vektorlistát, hogy megváltoztathassuk
myArray = [5,76,8,5,3,3,56,5,23]

# Ciklus indul nullától felfelé, az elemek számáig
# a vektorban:
for i in range( len(myArray) ):
	# Modify the element by doubling it
	myArray[i] = myArray[i] * 2

# Eredmény kiíratása
print( myArray )

Habár a kettes verzió nem működik a számsor megduplázásával. Miért? Mivel a lista eleme csupán egy másolata az eredeti listaelemnek. A lenti kód a másolatot másolja, nem az eredeti elemeket.

# Másoljuk le a vektorlistát, hogy megváltoztathassuk
myArray = [5,76,8,5,3,3,56,5,23]

# Ciklussal ismételjünk minden elemet a myArray változóban
for item in myArray:
	# Ez megduplázza az elemet, de nem fogja megváltoztatni
	# a listát, mivel az elem csak egy másolat.
	item = item * 2

# Eredmény kiírása
print( myArray )

7.6 Szövegek szeletelése

Videó: Szövegek szeletelése

A szövegek a karakterek listái. Ugyanúgy kezelendők, mint a listák, melyben minden betű egy elem. Futtasd le a következő kódot, x mindkét értékére:

x = "This is a sample string"
#x = "0123456789"

print("x=",x)

# Hozzáférés egy karakterhez
print("x[0]=",x[0])
print("x[1]=",x[1])

# Hozzáférés a jobb oldalról
print("x[-1]=",x[-1])

#  0-tól 5-ig kiírni az elemeket
print("x[:6]=",x[:6])
# A hatos elemtől kiíratás
print("x[6:]=",x[6:])
# Kiíratás 6-8
print("x[6:9]=",x[6:9])

A Pythonban a szövegek használhatóak matematikai műveletekkel. Próbáld ki az alábbi kódot, és lesd meg, mit csinál a Python vele:

a = "Hi"
b = "There"
c = "!"
print(a + b)
print(a + b + c)
print(3 * a)
print(a * 3)
print((a * 2) + (b * 2))

Lehetőség van arra, hogy megkapjuk a szöveg hosszát. Ugyanúgy ahogy lehetséges egy számsor hosszát megkapni.

a = "Hi There"
print(len(a))

b = [3,4,5,6,76,4,3,3]
print(len(b))

Mivel egy szöveg nem más, mint egy sorozat, ezért iterálhatjuk minden karakter elemét, ugyanúgy, mint egy számsorét:

for character in "This is a test.":
    print (character)

Gyakorlás: kezdd az alábbi kóddal:

months = "JanFebMarAprMayJunJulAugSepOctNovDec"

n = int(input("Enter a month number: "))

Írasd ki a három hónap rövidítést, aszerint, amilyen számot a felhasználó megad. (Számold ki a helyét a szövegen belül, aztán használd ezt az információt, hogy kiírasd a korrekt szövegrészt.)

7.7 Titkos kódok

Ez a kód egyenként kiírat minden betűt egy szövegből:

plain_text = "This is a test. ABC abc"

for c in plain_text:
    print (c, end=" ")
Videó: Titkos kódok

A számítógépek nem tárolják valójában a szöveg betűit a memóriában, hanem számsorokat tárolnak. Minden szám egy betűt jelöl. A rendszer, amit a számítógép használ, lefordítja a számokat betűkké, amit úgy nevezünk, hogy Unicode. A teljes neve Unverzális "Karakterkészletet Átalakító 8 bites formátum", amit gyakran rövidítenek UTF-8-nak.

Az Unicode táblázat lefedi a nyugati ABC-t, 0-127 számokkal jelölve azokat. Minden nyugati betű egy bájt memória helyén tárlódik. Más ABC-k, mint a cirill, már több bájtot vesz igénybe. Az Unicode tábla részletének másolata itt látható:

ValueCharacterValueCharacterValueCharacterValueCharacter
40(61=82R103g
41)62>83S104h
42*63?84T105i
43+64@85U106j
44,65A86V107k
45-66B87W108l
46.67C88X109m
47/68D89Y110n
48069E90Z111o
49170F91[112p
50271G92\113q
51372H93]114r
52473I94^115s
53574J95_116t
54675K96`117u
55776L97a118v
56877M98b119w
57978N99c120x
58:79O100d121y
59;80P101e122z
60<81Q102f

További információk az ASCII-ről (ami ugyanazzal az értékekkel számol, mint az Unicode a nyugati ABC-nél), lásd még:
http://en.wikipedia.org/wiki/ASCII

Nézz meg egy videót, ami felfedi a az Unicode csodálatos világát:
http://hackaday.com/2013/09/27/utf-8-the-most-elegant-hack

A következő pár sor kód minden betűt átalakít eredeti UTF-8 kódjelű számmá:

plain_text = "This is a test. ABC abc"

for c in plain_text:
    print (ord(c), end=" ")

A következő program minden UTF-8 értékhez egyet hozzáad. Azután, kiírja azt az új UTF-8 értéket, majd visszakonvertálja az értéket betűvé.

plain_text = "This is a test. ABC abc"

for c in plain_text:
    x = ord(c)
    x = x + 1
    c2 = chr(x)
    print (c2, end="")

A következő kód kilistáz minden UTF-8 értéket, és egyet hozzáad. Azután az értéket visszaalakítja betűvé.

fig.encryption
# Sample Python/Pygame Programs
# Simpson College Computer Science
# http://programarcadegames.com/
# http://simpson.edu/computer-science/

# Explanation video: http://youtu.be/sxFIxD8Gd3A

plain_text = "This is a test. ABC abc"

encrypted_text = ""
for c in plain_text:
    x = ord(c)
    x = x + 1
    c2 = chr(x)
    encrypted_text = encrypted_text + c2
print(encrypted_text)

Végül, az utolsó kód fogja az összes UTF-8 értéket és egyet kivon belőle. Azután az értéket visszaadja betűként. Ha használni akarjuk az előző programmal, akkor ez lehet a dekódolója a fenti kódnak.

fig.decryption
# Sample Python/Pygame Programs
# Simpson College Computer Science
# http://programarcadegames.com/
# http://simpson.edu/computer-science/

# Explanation video: http://youtu.be/sxFIxD8Gd3A

encrypted_text = "Uijt!jt!b!uftu/!BCD!bcd"

plain_text = ""
for c in encrypted_text:
    x = ord(c)
    x = x - 1
    c2 = chr(x)
    plain_text = plain_text + c2
print(plain_text)

7.8 Asszociatív számosorozatok

A Python nincs limitálva arra nézvést, hogy csak számot használhatna sorozat indexeként. Lehetséges használni asszociatív sorozatot. Egy asszociatív sorozat így működik:

# Készítsünk asszociatív listát
# (Figyeld meg a kapcsos zárójelet.)
x = {}

# Adjunk meg pár értéket
x["fred"] = 2
x["scooby"] = 8
x["wilma"] = 1

# Válasszunk ki egy elemet és írassuk ki
print(x["fred"])

Nincs igazából szükséged asszociatív sorozatra ebben az osztályban, de úgy gondolom, hogy ez egy fontos dolog, hogy lásd, hogy ez lehetséges.

7.9 Review

7.9.1 Multiple Choice Quiz

Click here for a multiple-choice quiz.

7.9.2 Short Answer Worksheet

Click here for the chapter worksheet.

7.9.3 Lab

Click here for the chapter lab.