Recent Changes - Search:

Oktatás

* Programozás 1
  + feladatsor
  + GitHub oldal

* Szkriptnyelvek
  + feladatsor
  + quick link

Teaching

* Programming 1 (BI)
  ◇ exercises
  ◇ quick link

* Scripting Languages
  ◇ exercises
  ◇ quick link

teaching assets


Félévek

* aktuális (2023/24/2)
* archívum


Linkek

* kalendárium
   - munkaszüneti napok '20
* tételsorok
* jegyzetek
* szakdolgozat / PhD
* ösztöndíjak
* certificates
* C lang.
* C++
* C#
* Clojure
* D lang.
* Java
* Nim
* Scala


[ edit | logout ]
[ sandbox | passwd ]

Py /

20170522a

map, reduce, filter

Ezek a függvények ismerősek lehetnek a funkcionális programozási nyelvekből.

map(function, iterable, …)

Veszi az iterálható objektum elemeit, s mindegyikre meghívja az első paraméterben megadott függvényt. A visszatérési érték egy iterátor lesz, amivel végig lehet menni az eredményen.

li = ["34", "98", "42"]
res = [int(n) for n in li]    # with a list comprehension
print(res)
print(type(res))
print('#')
res = map(int, li)            # apply the function int() on each element of li
print(res)
print(type(res))
for n in map(int, li):
    print(n, end=' ')
print()
print('#')
print(list(map(int, li)))     # convert to list
[34, 98, 42]
<class 'list'>
#
<map object at 0x7fe9e75effd0>
<class 'map'>
34 98 42 
#
[34, 98, 42]

Ahogy a 2. sorban látható, egy map() hívás megoldható list comprehension-nel is. Mégis, mi a különbség? Egy list comprehension egy listát állít elő, míg egy map() egy iterátort ad vissza. Viszont ha spórolni akarunk a memórival, akkor map() helyett használahatunk egy generator comprehension-t is.

Na jó, akkor mégis melyiket használjuk? Sokan úgy vélik (én is…), hogy egy comprehension olvashatóbb, így inkább azt használjuk. Ha nagyon rövid és még áttekinthető a map(), akkor az is használható. Pl. egy "map(int, my_list)" is szépen kiolvasható: "a my_list minden elemét alakítsuk át egésszé".

filter(function, iterable)

Ez tipikusan az a függvény, amit inkább NE használjunk, mert egy comprehension sokkal olvashatóbb lesz.

Veszi az iterálható objektum elemeit, s csak azokat adja vissza (tartja meg), amikre igaz értéket ad vissza az első paraméterben lévő függvény. A visszatérési érték egy iterátor lesz.

i = [3, 7, 1, 8, 5, 4, 2, 7, 9]
# let's filter (keep) the even elements
even = [n for n in li if n % 2 == 0]       # nice
print(even)
print('#')
even = filter(lambda x: x % 2 == 0, li)    # ugly
print(type(even))
print(list(even))
[8, 4, 2]
#
<class 'filter'>
[8, 4, 2]

functools.reduce(function, iterable[, initializer])

Ez régebben egy beépített függvény volt, de a Python 3-ban kegyvesztetté vált, s száműzték a functools modulba. Mivel a map()-pel és a filter()-rel együtt szokták emlegetni, ezért itt lesz róla szó.

from functools import reduce

def add(x, y):
    return x + y

def mul(x, y):
    return x * y

def main():
    li = [1,2,3,4,5]
    print(sum(li))
    print('#')
    print(reduce(add, li))    # sum of the elements
    print(reduce(mul, li))    # product of the elements
15
#
15
120

Az első paraméter egy függvény, a második egy iterálható objektum (amit most az egyszerűség kedvéért listának fogunk tekinteni). Megy végig a lista elemein balról jobbra, s elempárokkal dolgozik. Az első elempárra alkalmazza a függvényt (1. paraméter), s az eredményt visszateszi a lista elejére (vagy legalábbis így képzeljük el). Ezt addig folytatja, amíg végül egyetlen elem marad a listában. Ez lesz a végeredmény, ezzel fog visszatérni. Mint látható, a listát lépésenként redukálja, míg végül egy elem marad.

Van egy harmadik, opcionális paraméter is, egy inicializáló. Ha ez meg van adva, akkor ez bekerül a lista elejére, s utána indul a redukálás. Ha a lista (pontosabban: szekvencia) üres, akkor ez lesz a visszatérési érték. Ha a szekvencia 1-elemű, akkor ez az egyetlen elem lesz a visszatérési érték.

Nézzük meg a "reduce(add, [1,2,3,4,5])" futását:

reduce(add, [1,2,3,4,5])
1 + 2 = 3
reduce(add, [3,3,4,5])
3 + 3 = 6
reduce(add, [6,4,5])
6 + 4 = 10
reduce(add, [10,5])
10 + 5 = 15
reduce(add, [15])    # Oops, it has only 1 element!
return 15

A fenti példában hibát kapnánk az üres listára. Az inicializálót felhasználva így lesz helyes a kódunk:

li = []
print(reduce(add, li, 0))    # 0, as the sum of an empty list is 0 by definition
print(reduce(mul, li, 1))    # 1, as the product of an empty list is 1 by definition

Feladatok

  • Py3.20170522a felhőkarcolók (Próbáljuk meg használni a most tanult függvények valamelyikét!)

Linkek

Cloud City

  

Blogjaim, hobbi projektjeim

* The Ubuntu Incident
* Python Adventures
* @GitHub
* heroku
* extra
* haladó Python
* YouTube listák


Debrecen | la France


[ edit ]

Edit - History - Print *** Report - Recent Changes - Search
Page last modified on 2018 March 27, 12:38