Informatika1-2014/eloadas4

A MathWikiből
A lap korábbi változatát látod, amilyen Wettl (vitalap | szerkesztései) 2014. október 14., 09:01-kor történt szerkesztése után volt.

Listák

Ugyanúgy lehet szeletelni (slice), mint a karakterláncot:

>>> x = [1, 2, 3, 4]
>>> x[1]
2
>>> x[2:]
[3, 4]
>>> x[0::2]
[1, 3]
>>> x[:]
[1, 2, 3, 4]
>>> x[-1:-3]
[]
>>> x[-1:-3:-1]
[4, 3]
>>> x[-1::-1]
[4, 3, 2, 1]
<python>
 
Ugyanúgy lehet összeadni, többszörözni, mint a karakterláncot, de '''a lista változtatható (mutable)''':
 
<python>
>>> x = [1, 2, 3, 4]
>>> x[:2]*2 + x[-1:]
[1, 2, 1, 2, 4]
>>> x[:2]*2 + x[-1]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
TypeError: can only concatenate list (not "int") to list

Az értékadás (=) csak objektumhivatkozással jár, nem történik adatmásolás. Ennek következtében egy y = x parancs után, ahol x lista (vagy valamilyen más gyűjteményes adattípus), az y ugyanarra az objektumra fog mutatni. Így ha megváltoztatjuk x-et vagy y-t, változik a másik is. Az objektumhivatkozások megtörténhetnek egy szinttel mélyebben is, a (z = x[:] kód esetén az x elemeire mutató hivatkozások másolódnak, de ekkor sem jön létre a teljes objektumról másolat. Ezt hívjuk sekély másolásnak (shallow copy).


Egy másik példa sekély másolásra:

Mély másolás (deep copy), amikor valóban új példány keletkezik az objektumból:

import copy
w = copy.deepcopy(x)



Listák kezelése, metódusai

Lista létrehozható értékadással, [] az üres lista. A range parancs is listát ad vissza:

>>> range(3)
[0, 1, 2]
>>> range(3, 6)
[3, 4, 5]
>>> range(1,10,3)
[1, 4, 7]

A lehetséges metódusok például kiírhatók TAB billentyűvel ipythonban:

In [31]: x = range(1,5); x
Out[31]: [1, 2, 3, 4]
 
In [32]: x.append(99); x
Out[32]: [1, 2, 3, 4, 99]
 
In [33]: x.
x.append   x.extend   x.insert   x.remove   x.sort     
x.count    x.index    x.pop      x.reverse  
 
In [33]: x.extend([1,1,1]); x
Out[33]: [1, 2, 3, 4, 99, 1, 1, 1]
 
In [34]: x.count(1); x
Out[34]: [1, 2, 3, 4, 99, 1, 1, 1]
 
In [35]: x.index(2)
Out[35]: 1
 
In [36]: x.insert(4,5); x
Out[36]: [1, 2, 3, 4, 5, 99, 1, 1, 1]
 
In [37]: x.pop(5); x
Out[37]: [1, 2, 3, 4, 5, 1, 1, 1]
 
In [38]: x.re
x.remove   x.reverse  
 
In [38]: x.reverse(); x
Out[38]: [1, 1, 1, 5, 4, 3, 2, 1]
 
In [39]: x.remove(1); x
Out[39]: [1, 1, 5, 4, 3, 2, 1]
 
In [40]: x.sort(); x
Out[40]: [1, 1, 1, 2, 3, 4, 5]

Listaértelmezés

Írjuk egy listába a 100-nál kisebb nem negatív négyzetszámokat! Egy megoldás:

>>> negyzetek = []
>>> for x in range(10):
        negyzetek.append(x**2)
 
>>> negyzetek
[0, 1, 4, 9, 16, 25, 36, 49, 64, 81]

Egy egyszerű -- igazi Pythonos -- megoldás:

>>> negyzetek = [x**2 for x in range(10)]

Rövid listák létrehozásának egyszerű módja a listaértelmezés. Általános alakja:

[expression for expr in sequence1
            if condition1
            for expr2 in sequence2
            if condition2 
            ...
            for exprN in sequenceN
            if conditionN]

Kis programrészek helyettesíthetők vele. Például soroljuk fel az 1890 és 1915 közé eső szökőéveket!

szoko = []
for ev in range(1890, 1922):
    if (ev%4 == 0 and ev%100 != 0) or (ev%400 == 0):
        szoko.append(ev)
print szoko
[1892, 1896, 1904, 1908, 1912, 1916, 1920]

Lépésenként egyre összetettebb listaértelmezéssel állítsuk elő ugyanezt:

>>> szoko = [ev for ev in range(1890, 1915)]
>>> szoko    # ez még az összes év
[1890, 1891, 1892, 1893, 1894, 1895, 1896, 1897, 1898, 1899, 1900, 1901, 1902, 1903, 1904, 1905, 1906, 1907, 1908, 1909, 1910, 1911, 1912, 1913, 1914]
>>> szoko = [ev for ev in range(1890, 1915) if ev%4 == 0]
>>> szoko    # ez a 4-gyel osztható évek listája
[1892, 1896, 1900, 1904, 1908, 1912]
>>> szoko = [ev for ev in range(1890, 1915) 
                if (ev%4 == 0 and ev%100 != 0) or ev%400 == 0]
>>> szoko
[1892, 1896, 1904, 1908, 1912]
Személyes eszközök