W tym opracowaniu zgłębisz tajniki wykorzystania funkcji map()
w języku Python, która umożliwia zastosowanie określonej operacji do każdego elementu w zbiorze danych.
Python, jako język wspierający paradygmat programowania funkcyjnego, umożliwia definiowanie zadań poprzez operacje na funkcjach. Funkcje w Pythonie są traktowane jak obiekty, co oznacza, że mogą być przekazywane jako argumenty do innych funkcji, a także zwracane jako wyniki.
Funkcja map()
jest narzędziem, które przyjmuje inną funkcję jako argument i aplikuje ją do każdego elementu w sekwencji, zbiorze lub innej strukturze iterowalnej.
Po lekturze tego przewodnika, będziesz w stanie wykorzystać potencjał map()
w Pythonie do zastępowania tradycyjnych pętli oraz konstrukcji list składanych. Prześledzimy praktyczne przykłady, aby zrozumieć różne zastosowania tej funkcji.
Jak zaaplikować funkcję do elementów listy w Pythonie?
Rozpocznijmy od analizy konkretnego przypadku. 👩🏫
Załóżmy, że mamy listę liczb, którą nazwiemy nums
.
nums = [2,4,3,7]
Następnie, zdefiniujmy funkcję self_pow()
. Ta funkcja, przyjmując liczbę jako argument, zwróci jej wartość podniesioną do potęgi samej siebie, czyli n**n
.
W Pythonie operator potęgowania to **
. Wyrażenie a**b
oznacza a
podniesione do potęgi b
, czyli ab
.
def self_pow(n): return n**n
ZADANIE: Stworzenie nowej listy, nums_pow
, która będzie zawierać wyniki zastosowania funkcji self_pow()
do każdego elementu listy nums
.
Wykorzystanie pętli
Aby to osiągnąć, można użyć pętli for
w Pythonie:
- Dla każdej liczby w liście
nums
, wywołaj funkcjęself_pow()
z tą liczbą jako argumentem. - Dodaj wynik wywołania funkcji do nowej listy
nums_pow
.
nums_pow = [] for num in nums: nums_pow.append(self_pow(num)) print(nums_pow)
W rezultacie, każda liczba w nums
zostanie podniesiona do potęgi samej siebie. Elementy listy nums_pow
będą zatem: 22, 44, 33, 77.
Output [4, 256, 27, 823543]
Wykorzystanie list składanych
Możemy osiągnąć ten sam efekt bardziej zwięźle, stosując konstrukcję list składanych. Analizując powyższą pętlę for
, możemy wyodrębnić wyrażenie wyjściowe oraz listę, po której iterujemy.
Możemy zapisać ogólną konstrukcję listową jako:
new_list = [<wyrażenie wyjściowe> for item in iterable]
W kontekście generowania listy nums_pow
, wyrażenie listowe będzie wyglądało następująco:
nums_pow = [self_pow(num) for num in nums] print(nums_pow)
Oczekiwany wynik, analogiczny do tego z pętlą for
, zostanie wygenerowany.
Output [4, 256, 27, 823543]
Alternatywą dla pętli i list składanych jest funkcja map()
w Pythonie. Charakteryzuje się ona zwięzłą składnią i ułatwia aplikowanie funkcji do wszystkich elementów struktury iterowalnej. Przejdźmy do analizy składni tej funkcji.
Składnia funkcji map()
w Pythonie
Ogólna forma funkcji map()
prezentuje się następująco:
map(funkcja, iterowalny_1,[iterowalny_2,...,iterowalny_n])
Funkcja map()
przyjmuje co najmniej dwa parametry: funkcję oraz element iterowalny.
W powyższej konstrukcji:
funkcja
oznacza dowolną funkcję Pythona, w tym funkcje wbudowane, zdefiniowane przez użytkownika, klasy, instancje klas, metody oraz wiele innych obiektów wywoływalnych.iterowalny
to dowolna struktura iterowalna w Pythonie, na przykład lista, krotka, czy ciąg znaków.- Działanie funkcji
map()
polega na zastosowaniu podanejfunkcji
do każdego elementu w strukturzeiterowalnej
.
Co zwraca funkcja map()
?
Zwraca ona obiekt mapy. Możesz następnie przekształcić ten obiekt w listę za pomocą konstrukcji: list(map(funkcja, iterowalny))
.
W zależności od potrzeb, obiekt mapy może zostać przekształcony w krotkę.
Teraz, gdy znasz już składnię funkcji map()
, przejdźmy do praktycznych przykładów.
Dla celów tego tutoriala, zalecane jest posiadanie zainstalowanej wersji Pythona 3.x. Alternatywnie, kod można uruchamiać w internetowym edytorze Pythona newsblog.pl.
Jak używać funkcji map()
z funkcjami zdefiniowanymi przez użytkownika?
#1. Wcześniej wykorzystywaliśmy funkcję self_pow()
dla każdej liczby w liście nums
. Wykorzystując składnię funkcji map()
, możemy przekazać funkcję self_pow
oraz elementy listy nums
jako argumenty.
Uwaga: Podajemy tylko nazwę funkcji, a nie jej wywołanie. Użyj self_pow
, a nie self_pow()
.
Funkcja map()
zwróci obiekt mapy.
print(map(self_pow,nums)) <map object at 0x7f7d315c14d0>
Następnie, obiekt mapy możemy przekształcić w listę za pomocą funkcji list()
, jak widać poniżej.
nums_pow = list(map(self_pow,nums)) print(nums_pow)
Oto wynik, gdzie każdy element num
z listy nums
został przekształcony na numnum
w liście nums_pow
.
Output [4, 256, 27, 823543]
#2. Rozważmy funkcję inch_to_cm()
, która dokonuje konwersji cali na centymetry. 1 cal = 2.54 cm.
def inch_to_cm(inch): return inch*2.54
Aby dokonać konwersji wartości cali z listy na centymetry, użyjemy funkcji map()
, jak przedstawiono w poniższym fragmencie kodu.
inches = [5.54,3.4,1,25,8.2] cms = list(map(inch_to_cm,inches)) print(cms)
Lista cms
zawiera wartości z listy inches
, wyrażone w centymetrach.
Output [14.0716, 8.636, 2.54, 63.5, 20.828]
Jak wykorzystać funkcję map()
z wbudowanymi funkcjami?
W tej sekcji, zapoznamy się z wykorzystaniem funkcji map()
w połączeniu z wbudowanymi funkcjami Pythona.
#1. Załóżmy, że mamy listę strings
, zawierającą nazwy języków programowania. Chcemy utworzyć nową listę, strings_upper
, w której wszystkie nazwy będą zapisane wielkimi literami.
strings = ['JavaScript','Rust','Python','Go']
Wbudowana metoda łańcuchowa .upper()
, zastosowana do łańcucha znaków, zwraca jego kopię zapisaną wielkimi literami.
strings_upper = list(map(str.upper,strings)) print(strings_upper)
Lista strings_upper
zawiera łańcuchy znaków z listy strings
, sformatowane wielkimi literami.
Output ['JAVASCRIPT', 'RUST', 'PYTHON', 'GO']
#2. Wbudowana funkcja len()
w Pythonie przyjmuje sekwencję jako argument i zwraca jej długość. Aby określić długość każdego łańcucha w liście strings
, możemy zastosować funkcję map()
, wywołując funkcję len
na każdym z łańcuchów, jak poniżej.
strings_len = list(map(len,strings)) print(strings_len)
Output [10, 4, 6, 2]
#3. Funkcję map()
możemy stosować również z innymi kolekcjami, na przykład z krotkami.
Poniższy przykład przedstawia krotkę zawierającą informacje o liczbie sypialni, powierzchni i mieście, w którym znajduje się nieruchomość.
W Pythonie funkcja type()
zwraca typ danych dowolnego obiektu. Aby poznać typ danych każdego elementu w krotce, można zastosować funkcję map()
, wywołując type
na każdym elemencie krotki.
house = (2,758.5,'Bangalore') house_elt_type = tuple(map(type,house)) print(house_elt_type)
Obiekt mapy został rzutowany na krotkę. Możliwe jest również rzutowanie na listę, bądź inną kolekcję.
W poniższym wyniku, widzimy, że typy danych dla wartości 2, 758.5 oraz 'Bangalore’ zostały prawidłowo rozpoznane jako 'int’, 'float’ i 'str’.
Output (<class 'int'>, <class 'float'>, <class 'str'>)
#4. W Pythonie, możliwe jest importowanie wbudowanych modułów i używanie funkcji w nich zdefiniowanych.
Aby obliczyć pierwiastek kwadratowy każdej liczby w liście nums
, możemy wykorzystać funkcję sqrt
z modułu math
.
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]
Powyższe dane wyjściowe są trudne w analizie i interpretacji. Może okazać się konieczne zaokrąglenie każdej wartości pierwiastka kwadratowego do dwóch miejsc po przecinku.
Jak zaokrąglić liczbę zmiennoprzecinkową w Pythonie?
Zdefiniujmy funkcję round_2()
, która przyjmuje liczbę zmiennoprzecinkową jako argument i zaokrągla ją do dwóch miejsc po przecinku.
def round_2(num): return round(num,2)
Teraz, możemy wykorzystać funkcję map()
w połączeniu z round_2
i 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]
Możliwe jest również użycie zagnieżdżonych funkcji map()
, gdzie wewnętrzna map
służy do obliczania pierwiastków kwadratowych (nums_sqrt
), a zewnętrzna map
realizuje operację zaokrąglania.
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]
Wyniki obu podejść są identyczne. Należy jednak zadbać o czytelność i łatwość utrzymania kodu podczas zagnieżdżania funkcji, jak przedstawiono powyżej.
Jak używać funkcji map()
z funkcjami lambda
W poprzednich rozdziałach, nauczyliśmy się używać funkcji map()
w Pythonie z funkcjami wbudowanymi oraz zdefiniowanymi przez użytkownika. Teraz dowiemy się, jak wykorzystać funkcję map()
z funkcjami lambda
, które w Pythonie są anonimowe.
W sytuacjach, gdy ciało funkcji składa się tylko z jednej linii kodu i potrzebujemy jej użyć tylko raz, bez odwoływania się do niej w innych częściach programu, możemy zdefiniować ją jako funkcję lambda
.
Uwaga: lambda argumenty: wyrażenie
to ogólna składnia definiowania funkcji lambda
w Pythonie.
#1. Rozważmy listę łańcuchów znaków. Chcemy uzyskać nową listę, strings_rev
, w której łańcuchy znaków będą odwrócone.
strings = ['JavaScript','Rust','Python','Go']
Możemy odwrócić łańcuch znaków w Pythonie, stosując technikę krojenia łańcuchów (ang. string slicing).
Uwaga: Jest to ogólna forma wyrażenia krojącego łańcuch str[start:stop:step]
.
– Jeżeli wartości start
i stop
nie są zdefiniowane, wycinek zaczyna się na początku łańcucha i kończy na jego końcu.
– Ujemne wartości kroku (step
) powodują, że wycinek tworzony jest od końca łańcucha.
– Dlatego wyrażenie str[::-1]
zwraca odwróconą kopię str
.
Możemy użyć funkcji lambda
: lambda x:x[::-1]
, wewnątrz funkcji map
, jak przedstawiono poniżej.
strings_rev = list(map(lambda x:x[::-1],strings)) print(strings_rev)
Podobnie jak w innych przykładach, obiekt mapy jest przekształcany na listę. W wyniku, każdy łańcuch z listy strings
zostaje odwrócony.
Output ['tpircSavaJ', 'tsuR', 'nohtyP', 'oG']
#2. W poprzedniej sekcji, obliczaliśmy pierwiastek kwadratowy każdej liczby z listy, a następnie zaokrąglaliśmy wyniki do dwóch miejsc po przecinku.
W tym celu, używaliśmy funkcji round_2()
. Przekształćmy teraz funkcję round_2()
w funkcję lambda
i zastosujmy ją w połączeniu z funkcją map()
, jak niżej.
nums_sqrt_round_l =list(map(lambda num:round(num,2),nums_sqrt)) print(nums_sqrt_round_l)
Jak widzimy, uzyskany wynik jest identyczny z tym, który otrzymaliśmy przy użyciu funkcji round_2()
.
Output [5.48, 9.49, 5.83, 6.71, 9.85]
Jak używać funkcji map()
z wieloma elementami iterowalnymi?
W omawianych dotychczas przykładach, funkcja była aplikowana do elementów tylko jednej struktury iterowalnej.
Czasami, możemy mieć funkcje, które przyjmują dwa, lub więcej argumentów. W takich przypadkach, każdy z argumentów przechowywany jest na oddzielnej liście, lub w innej podobnej kolekcji.
Możemy również używać funkcji map()
w Pythonie z wieloma listami.
#1. Rozważmy funkcję area()
, która przyjmuje długość i szerokość jako argumenty, i zwraca pole powierzchni, czyli długość * szerokość
.
def area(length,breadth): return length*breadth
Długości i szerokości różnych prostokątów przechowywane są w dwóch odrębnych listach, odpowiednio lengths
i breadths
.
lengths = [4,8,10,18] breadths = [9,4,6,11]
Możemy użyć funkcji map()
, aby zastosować funkcję area
do powyższych list, przekazując obie listy lengths
i breadths
.
areas = list(map(area,lengths,breadths)) print(areas)
Ponieważ funkcja area
przyjmuje dwa argumenty, wartości z list lengths
i breadths
będą traktowane jako argumenty funkcji.
Output [36, 32, 60, 198]
#2. Moduł matematyczny Pythona posiada funkcję log
, która pozwala nam obliczyć logarytm liczby o dowolnej podstawie.
Uwaga: log(x, podstawa)
zwraca wartość logarytmu liczby x
o podstawie zdefiniowanej przez podstawa
. Jeżeli podstawa
nie jest zdefiniowana, domyślną wartością jest e
(logarytm naturalny).
W tym przykładzie:
- Lista
x
zawiera wartości, dla których chcemy obliczyć logarytm. - Lista
base
zawiera wartości podstaw, które mają być użyte w obliczeniach logarytmicznych.
x = [2,6,12,10] base = [2,3,2,5]
Możemy użyć funkcji map()
z math.log
oraz listami x
i base
, aby utworzyć nową listę log_x
.
log_x = list(map(math.log,x,base)) print(log_x)
Oto rezultat.
Output [1.0, 1.6309297535714573, 3.5849625007211565, 1.4306765580733933]
Podsumowanie
Poniżej znajduje się podsumowanie kluczowych punktów, które poznałeś w tym samouczku:
- Funkcja
map()
w Pythonie przyjmuje co najmniej dwa argumenty: funkcję i iterowalną strukturę danych, zgodnie ze składniąmap(funkcja, iterowalny(e))
. funkcja
może być dowolnym obiektem wywoływalnym w Pythonie.- Gdy funkcja przyjmuje
k
argumentów, można użyćmap()
z funkcją orazk
elementami iterowalnymi.
Następnym krokiem będzie nauka pracy ze zbiorami danych w Pythonie.