V tomto návodu si osvojíte použití funkce map()
v Pythonu, která umožňuje aplikovat danou funkci na všechny prvky iterovatelné struktury.
Python podporuje funkcionální programování, což znamená, že úkoly můžete definovat jako výpočty nad funkcemi. S funkcemi v Pythonu můžete pracovat jako s objekty: funkce může přijímat jinou funkci jako parametr a také vracet jinou funkci.
Funkce map()
akceptuje funkci jako argument a umožňuje aplikovat ji na každý prvek v sekvenci.
Po prostudování tohoto tutoriálu budete schopni efektivně používat funkci map()
v Pythonu, což vám umožní zjednodušit komplikované cykly a konstrukce list comprehension. Předvedeme si několik praktických příkladů, abyste pochopili různé způsoby, jak můžete funkci map()
využít.
Aplikace Funkce na Prvky Seznamu v Pythonu
Začněme tuto diskuzi názorným příkladem. 👩🏫
Mějme seznam čísel nums
:
nums = [2,4,3,7]
Dále uvažujme funkci self_pow()
, která přijímá číslo jako vstup a vrací toto číslo umocněné na sebe sama (n**n).
V Pythonu je **
operátor umocňování. Výraz a**b
vrátí hodnotu a
umocněnou na b
(tj. ab).
def self_pow(n): return n**n
Cíl: Vytvořit nový seznam nums_pow
aplikováním funkce self_pow()
na každý prvek v seznamu nums
.
Použití cyklu for
K dosažení tohoto cíle můžete použít cyklus for
v Pythonu:
- Pro každé číslo v seznamu
nums
zavoláme funkciself_pow()
s daným číslem jako argumentem. - Výsledek volání funkce přidáme do nového seznamu
nums_pow
.
nums_pow = [] for num in nums: nums_pow.append(self_pow(num)) print(nums_pow)
Ve výstupu vidíme, že každé číslo num
je umocněno na sebe sama. Prvky v seznamu nums_pow
jsou: 22, 44, 33, 77.
Output [4, 256, 27, 823543]
Použití list comprehension
Elegantnějšího řešení můžeme dosáhnout pomocí list comprehension. Z předchozího cyklu for
můžeme identifikovat výraz pro výstup a seznam, přes který iterujeme.
Poté můžeme zobecnit výraz pro list comprehension:
novy_seznam = [<výstupní výraz> for prvek in iterovatelný]
Výraz list comprehension pro generování seznamu nums_pow
je následující:
nums_pow = [self_pow(num) for num in nums] print(nums_pow)
Výstup je, jak se očekává, stejný jako při použití cyklu for
.
Output [4, 256, 27, 823543]
Alternativou k cyklům a list comprehensions je použití funkce map()
v Pythonu. S její pomocí můžeme dosáhnout stejného výsledku pomocí stručné syntaxe a aplikovat funkci na každý prvek iterovatelné struktury. Pojďme se seznámit se syntaxí funkce map()
.
Syntaxe funkce map()
v Pythonu
Obecná syntaxe pro použití funkce map()
v Pythonu je:
map(funkce, iterovatelný_1,[iterovatelný_2,...,iterovatelný_n])
Funkce map()
vyžaduje alespoň dva argumenty: funkci a iterovatelnou strukturu.
V syntaxi výše:
funkce
označuje funkci v Pythonu nebo obecně jakoukoli volatelnou funkci. To zahrnuje jak uživatelsky definované, tak vestavěné funkce, třídy, metody instancí a tříd a další.iterovatelný
je jakákoli platná iterovatelná struktura v Pythonu, například seznam, n-tice nebo řetězec.- Funkce
map()
aplikuje zadanou funkci na každý prvek v iterovatelné struktuře.
Co funkce map()
vrací?
Funkce vrací objekt typu map
. Tento objekt můžeme přetypovat na seznam pomocí syntaxe: list(map(funkce,iterovatelný))
.
V závislosti na potřebě můžeme tento objekt přetypovat i na n-tici v Pythonu.
Nyní, když známe syntaxi funkce map()
, můžeme se podívat na příklady kódování.
Pro tento tutoriál byste měli mít Python 3.x. V opačném případě můžete úryvky kódu spouštět v online editoru Python například na stránce etechblog.cz.
Použití funkce map()
s uživatelsky definovanými funkcemi
#1. Již dříve jsme aplikovali funkci self_pow()
na každé číslo v seznamu čísel. V syntaxi funkce map()
můžeme funkci self_pow
a seznam nums
předat jako argumenty.
Poznámka: Musíme zadat pouze název funkce, nikoli její volání. Použijte self_pow
a nikoli self_pow()
.
Funkce map()
vrací objekt typu map.
print(map(self_pow,nums)) <map object at 0x7f7d315c14d0>
Nyní můžeme objekt mapy přetypovat do seznamu pomocí funkce list()
, jak je uvedeno níže.
nums_pow = list(map(self_pow,nums)) print(nums_pow)
Zde je výstup, kde je každé číslo num
v nums
zmapováno na num
num v seznamu nums_pow
.
Output [4, 256, 27, 823543]
#2. Uvažujme funkci inch_to_cm()
, která převádí palce na centimetry. 1 palec = 2,54 cm.
def inch_to_cm(inch): return inch*2.54
Chceme-li převést hodnoty v palcích ze seznamu inches
na centimetry, můžeme použít funkci map()
, jak je uvedeno v kódu níže.
inches = [5.54,3.4,1,25,8.2] cms = list(map(inch_to_cm,inches)) print(cms)
Seznam cms
obsahuje hodnoty zadané v palcích, převedené na centimetry.
Output [14.0716, 8.636, 2.54, 63.5, 20.828]
Použití funkce map()
s vestavěnými funkcemi
V této části se naučíme používat funkci map()
s vestavěnými funkcemi v Pythonu.
#1. Mějme seznam programovacích jazyků strings
. Chceme vytvořit nový seznam strings_upper
, který bude obsahovat stejné názvy jazyků převedené na velká písmena.
strings = ['JavaScript','Rust','Python','Go']
Vestavěná metoda řetězců .upper()
transformuje řetězec a vrací jeho kopii převedenou na velká písmena.
strings_upper = list(map(str.upper,strings)) print(strings_upper)
Seznam strings_upper
obsahuje řetězce ze seznamu strings
formátované velkými písmeny.
Output ['JAVASCRIPT', 'RUST', 'PYTHON', 'GO']
#2. Vestavěná funkce len()
v Pythonu přijímá sekvenci jako argument a vrací její délku. Pro získání délek každého z řetězců v seznamu strings
můžeme použít funkci map()
a aplikovat funkci len
na každý z řetězců, jak je ukázáno níže.
strings_len = list(map(len,strings)) print(strings_len)
Output [10, 4, 6, 2]
#3. Funkci map()
můžete použít i s jinými kolekcemi, například s n-ticemi.
Následující příklad obsahuje n-tici s informacemi o počtu ložnic, rozloze a městě, kde se dům nachází.
V Pythonu funkce type()
vrací datový typ libovolného objektu. Pro získání datového typu všech položek v této n-tici můžeme použít funkci map()
a aplikovat type
na každou položku.
house = (2,758.5,'Bangalore') house_elt_type = tuple(map(type,house)) print(house_elt_type)
Objekt typu map jsme přetypovali na n-tici. Můžete ho ale také převést na seznam nebo jinou kolekci.
Ve výstupu vidíme, že datové typy pro hodnoty 2, 758.5 a Bangalore byly zjištěny jako ‚int‘, ‚float‘ a ‚str‘.
Output (<class 'int'>, <class 'float'>, <class 'str'>)
#4. V Pythonu můžete importovat vestavěné moduly a používat funkce, které jsou v nich definovány.
Pro výpočet druhé odmocniny každého čísla v seznamu čísel můžeme použít funkci sqrt
z matematického modulu.
import math nums = [30,90,34,45,97] nums_sqrt = list(map(math.sqrt,nums)) print(nums_sqrt)
Output [5.477225575051661, 9.486832980505138, 5.830951894845301, 6.708203932499369, 9.848857801796104]
Výše uvedený výstup je složitý pro čtení a analýzu. Můžeme chtít každou druhou odmocninu zaokrouhlit na dvě desetinná místa.
Zaokrouhlení čísel s plovoucí desetinnou čárkou v Pythonu
Pojďme definovat funkci round_2()
, která vezme číslo s plovoucí desetinnou čárkou a zaokrouhlí ho na dvě desetinná místa.
def round_2(num): return round(num,2)
Nyní můžeme použít funkci map()
se seznamem round_2
a nums_sqrt
.
nums_sqrt_round = list(map(round_2,nums_sqrt)) print(nums_sqrt_round)
Output [5.48, 9.49, 5.83, 6.71, 9.85]
Můžeme také použít vnořené funkce map()
, kde se vnitřní map
používá pro výpočet druhé odmocniny seznamu nums_sqrt
a vnější map
provádí zaokrouhlení.
nums_sqrt_round = list(map(round_2,list(map(math.sqrt,nums)))) print(nums_sqrt_round)
Output [5.48, 9.49, 5.83, 6.71, 9.85]
Výstupy jsou v obou výše uvedených přístupech identické. Nicméně bychom měli dbát na čitelnost a udržovatelnost kódu, když vnořujeme funkce tak, jak je ukázáno výše.
Použití funkce map()
s lambda funkcemi
V předchozích částech jsme se naučili, jak používat funkci map()
v Pythonu s vestavěnými a uživatelsky definovanými funkcemi. Nyní si ukážeme, jak používat funkci map()
s lambda funkcemi, které jsou v Pythonu anonymní.
Často se stane, že máme funkci, která má pouze jednořádkové tělo a pravděpodobně budeme potřebovat použít ji pouze jednou a dále na ni nebudeme odkazovat v celém programu. Takové funkce můžeme definovat jako lambda funkce v Pythonu.
Poznámka: lambda args: expression
je obecná syntaxe pro lambda funkce v Pythonu.
#1. Mějme opět seznam strings
. Představme si, že chceme získat seznam strings_rev
, který bude obsahovat obrácenou kopii každého řetězce.
strings = ['JavaScript','Rust','Python','Go']
Řetězec v Pythonu můžeme obrátit pomocí slicing (řezání) řetězce.
Poznámka: Toto je zobecnění výrazu pro slicing str[start:stop:step]
.
– Bez počáteční a koncové hodnoty začíná řez na začátku řetězce a sahá až na konec.
– Záporné hodnoty kroku dělají řezy od konce řetězce.
– Proto str[::-1]
vrátí obrácenou kopii str
.
Můžeme použít lambda funkci lambda x:x[::-1]
uvnitř funkce map()
, jak je ukázáno níže.
strings_rev = list(map(lambda x:x[::-1],strings)) print(strings_rev)
Jako v předchozích příkladech přetypujeme objekt mapy na seznam. Ve výstupu vidíme, že každý řetězec v seznamu byl obrácen.
Output ['tpircSavaJ', 'tsuR', 'nohtyP', 'oG']
#2. V předchozí části jsme vypočítali druhou odmocninu každého čísla v seznamu čísel a poté jsme každou hodnotu zaokrouhlili na dvě desetinná místa.
K tomuto účelu jsme použili funkci round_2()
. Nyní přepíšeme funkci round_2()
jako lambda funkci a použijeme ji s funkcí map()
, jak je popsáno níže.
nums_sqrt_round_l =list(map(lambda num:round(num,2),nums_sqrt)) print(nums_sqrt_round_l)
Jak můžeme vidět níže, výstup je identický s tím, co jsme dostali při použití funkce round_2()
.
Output [5.48, 9.49, 5.83, 6.71, 9.85]
Použití funkce map()
s více iterovatelnými strukturami
V příkladech, které jsme viděli, jsme aplikovali funkci na všechny prvky jedné iterovatelné struktury.
Někdy ale máme funkce, které přijímají dva nebo více argumentů. V tomto případě je každý argument uložen v seznamu nebo podobné kolekci.
Můžeme použít funkci map()
v Pythonu i s více seznamy.
#1. Uvažujme funkci area()
, která přijímá délku a šířku jako vstupy a vrací obsah obdélníku, délka * šířka.
def area(length,breadth): return length*breadth
Délky a šířky různých obdélníků jsou uloženy ve dvou samostatných seznamech, lengths
a breadths
.
lengths = [4,8,10,18] breadths = [9,4,6,11]
Můžeme použít funkci map()
pro aplikování funkce area
na výše uvedené seznamy tak, že jí předáme oba seznamy, lengths
a breadths
.
areas = list(map(area,lengths,breadths)) print(areas)
Protože funkce area
akceptuje dva argumenty, hodnoty délky a šířky jsou použity ze seznamů lengths
a breadths
.
Output [36, 32, 60, 198]
#2. Matematický modul Pythonu má funkci log
, která nám pomáhá počítat logaritmus čísla o libovolném základu.
Poznámka: log(x, base)
vrací hodnotu log
x
o základu určeném hodnotou base
, neboli log base x
. Pokud není zadán žádný základ, výchozí hodnotou je e
(logaritmus se počítá jako přirozený logaritmus).
V tomto příkladě:
- Seznam
x
odpovídá hodnotám, pro které chceme vypočítat logaritmus. - Seznam
base
obsahuje všechny základní hodnoty pro výpočet logaritmů.
x = [2,6,12,10] base = [2,3,2,5]
Můžeme použít funkci map()
z Pythonu spolu s math.log
a seznamy x
a base
a získat tak nový seznam log_x
, jak je ukázáno níže.
log_x = list(map(math.log,x,base)) print(log_x)
A zde je výstup.
Output [1.0, 1.6309297535714573, 3.5849625007211565, 1.4306765580733933]
Závěr
Zde je shrnutí toho, co jste se v tomto tutoriálu naučili:
- Funkce
map()
v Pythonu vyžaduje alespoň dva argumenty: funkci a iterovatelnou strukturu, a má syntaximap(funkce, iterovatelná_struktura(y))
. - Argument
funkce
může být jakákoli validní volatelná funkce v Pythonu. - Pokud funkce akceptuje
k
argumentů, můžeme použít funkcimap()
s danou funkcí ak
iterovatelnými strukturami.
Prohlubte si vaše znalosti a naučte se dále pracovat se sadami v Pythonu.