Funkce Python map() vysvětlená na příkladech

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 funkci self_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 numnum 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á syntaxi map(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 funkci map() s danou funkcí a k iterovatelnými strukturami.

Prohlubte si vaše znalosti a naučte se dále pracovat se sadami v Pythonu.