Lær Python map(): Funksjonell programmering med eksempler

I denne veiledningen skal vi utforske hvordan du anvender Python sin `map()`-funksjon for å prosessere hvert element i en samling med en gitt funksjon.

Python støtter en funksjonell programmeringsstil, hvor oppgaver defineres som funksjonsberegninger. Dette betyr at du kan behandle funksjoner som objekter, og at en funksjon kan ta en annen funksjon som argument, eller returnere en annen funksjon.

`map()`-funksjonen er et kraftig verktøy som tar en funksjon som argument og anvender den på hvert element i en sekvens.

Etter denne veiledningen vil du være i stand til å benytte deg av `map()`-funksjonen i Python for å erstatte detaljerte løkker og listeforståelser. Vi skal se på flere eksempler for å forstå de ulike måtene `map()` kan brukes på.

Hvordan bruke en funksjon på elementer i en Python-liste

La oss begynne med et praktisk eksempel. 👩‍🏫

Vi starter med en liste kalt `nums` som inneholder tall.

nums = [2,4,3,7]

Vi definerer også en funksjon `self_pow()`. Denne funksjonen tar et tall som inngang og returnerer tallet opphøyd i seg selv, altså `n**n`.

I Python er `**` eksponentieringsoperatoren. `a**b` gir verdien av `a` opphøyd i `b`, eller `ab`.

def self_pow(n):
    return n**n

OPPGAVE: Lag en ny liste `nums_pow` ved å bruke `self_pow()` på hvert element i `nums`.

Bruk av For-løkke

En måte å gjøre dette på er ved å bruke en `for`-løkke:

  • For hvert tall i `nums`, kall `self_pow()` med tallet som argument.
  • Legg til resultatet fra funksjonskallet til den nye listen `nums_pow`.
nums_pow = []

for num in nums:
  nums_pow.append(self_pow(num))

print(nums_pow)

Utdataene viser at hvert tall er opphøyd i seg selv. Elementene i `nums_pow` blir da: 22, 44, 33, 77.

Output
[4, 256, 27, 823543]

Bruk av listeforståelse

En mer konsis måte å gjøre det på er ved å bruke listeforståelse. Fra den eksplisitte `for`-løkken kan vi identifisere uttrykket som genererer utdataene og listen vi itererer over.

Vi kan bruke dette generelle listeforståelsesuttrykket:

new_list = [<uttrykk for utdata> for element in iterabel]

Listeforståelsen for å generere `nums_pow` er:

nums_pow = [self_pow(num) for num in nums]
print(nums_pow)

Utdataene er de samme som fra `for`-løkken, som forventet.

Output
[4, 256, 27, 823543]

I stedet for løkker og listeforståelse kan du bruke Python sin `map()`-funksjon, som gir en mer kortfattet syntaks og hjelper deg med å anvende en funksjon på alle elementene i en samling. La oss først se på syntaksen til `map()`.

`map()`-funksjonens syntaks

Den generelle syntaksen for `map()`-funksjonen er:

map(funksjon, iterabel_1,[iterabel_2,...,iterabel_n])

`map()`-funksjonen tar minst to argumenter, en funksjon og en iterabel.

I syntaksen over:

  • `funksjon` angir en Python-funksjon eller en hvilken som helst Python-kallbar. Dette inkluderer brukerdefinerte og innebygde funksjoner, klasser, instans- og klassemetoder, med mer.
  • `iterabel` er en hvilken som helst gyldig Python-iterabel, for eksempel en liste, tuppel eller streng.
  • `map()` anvender den spesifiserte `funksjon` på hvert element i den gitte `iterabel`.

Hva returnerer `map()`-funksjonen?

Den returnerer et `map`-objekt. Du kan konvertere dette `map`-objektet til en liste ved å bruke: `list(map(funksjon, iterabel))`.

Avhengig av bruken kan du også konvertere det til en tuppel.

Nå som vi har sett på syntaksen, la oss se på noen eksempler.

Du bør ha Python 3.x installert for å følge eksemplene. Alternativt kan du bruke en online Python-editor.

Bruk av `map()` med brukerdefinerte funksjoner

#1. Vi brukte tidligere funksjonen `self_pow()` på hvert tall i `nums`-listen. Med `map()` kan vi sende inn funksjonen `self_pow` og listen `nums` som argumenter.

Viktig: Du skal bare oppgi funksjonsnavnet, ikke selve funksjonskallet. Bruk `self_pow`, ikke `self_pow()`.

`map()`-funksjonen returnerer et `map`-objekt.

print(map(self_pow,nums))

<map object at 0x7f7d315c14d0>

Vi kan konvertere `map`-objektet til en liste med `list()`, som vist nedenfor.

nums_pow = list(map(self_pow,nums))
print(nums_pow)

Dette gir oss utdataene hvor hvert tall i `nums` er transformert til numnum i `nums_pow`-listen.

Output
[4, 256, 27, 823543]

#2. Se på funksjonen `inch_to_cm()` som konverterer tommer til centimeter. 1 tomme = 2,54 cm.

def inch_to_cm(inch):
  return inch*2.54

For å konvertere tommer-verdiene i `inches`-listen til centimeter, kan vi bruke `map()` som i eksemplet under.

inches = [5.54,3.4,1,25,8.2]
cms = list(map(inch_to_cm,inches))
print(cms)

`cms`-listen inneholder nå tommeverdiene uttrykt i centimeter.

Output
[14.0716, 8.636, 2.54, 63.5, 20.828]

Bruk av `map()` med innebygde funksjoner

Her ser vi på hvordan du kan bruke `map()` med Pythons innebygde funksjoner.

#1. `strings` er en liste med strenger som representerer programmeringsspråk. Vi vil lage en ny liste `strings_upper` med strengene i store bokstaver.

strings = ['JavaScript','Rust','Python','Go']

Den innebygde strengmetoden `.upper()` konverterer en streng til store bokstaver.

strings_upper = list(map(str.upper,strings)) 
print(strings_upper)

`strings_upper` inneholder nå strengene i `strings` med store bokstaver.

Output
['JAVASCRIPT', 'RUST', 'PYTHON', 'GO']

#2. Den innebygde `len()`-funksjonen tar en sekvens som argument og returnerer lengden. For å finne lengden av hver streng i `strings`, kan vi bruke `map()` til å bruke `len()` på hver streng.

strings_len = list(map(len,strings))
print(strings_len)
Output
[10, 4, 6, 2]

#3. `map()` kan også brukes med andre samlinger som tupler.

Følgende eksempel viser en tuppel som inneholder informasjon om antall soverom, areal og by for et hus.

I Python returnerer `type()` datatypen til et objekt. For å finne datatypen til alle elementene i denne tuppelen, kan du bruke `map()` til å kalle `type()` på hvert element.

house = (2,758.5,'Bangalore')
house_elt_type = tuple(map(type,house))
print(house_elt_type)

Vi har konvertert `map`-objektet til en tuppel. Du kan også konvertere det til en liste eller en annen samling.

Utdataene viser at datatypene til 2, 758.5 og Bangalore er identifisert som henholdsvis «int», «float» og «str».

Output
(<class 'int'>, <class 'float'>, <class 'str'>)

#4. I Python kan du importere innebygde moduler og bruke funksjonene som er definert i disse modulene.

For å beregne kvadratroten av hvert tall i `nums`-listen, kan du bruke `sqrt`-funksjonen fra `math`-modulen.

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]

Disse utdataene kan være vanskelige å analysere. Det kan være nyttig å runde hver kvadratrotverdi til for eksempel to desimaler.

Hvordan avrunde et flyttall i Python

La oss definere en funksjon `round_2()` som tar et flyttall og runder det av til to desimaler.

def round_2(num):
  return round(num,2)

Nå kan vi bruke `map()` med `round_2` og `nums_sqrt`-listen.

nums_sqrt_round = list(map(round_2,nums_sqrt))
print(nums_sqrt_round)
Output
[5.48, 9.49, 5.83, 6.71, 9.85]

Du kan også bruke nestede `map()`-funksjoner, der den indre `map()` brukes til å beregne kvadratrotlisten `nums_sqrt`, og den ytre `map()` utfører avrundingen.

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]

Utdataene er de samme for begge tilnærminger. Det er viktig å sørge for at koden er lesbar og vedlikeholdbar når man bruker nestede funksjoner som dette.

Bruk av `map()` med Lambda-funksjoner

Vi har nå sett hvordan `map()` kan brukes med innebygde og brukerdefinerte funksjoner. La oss nå se på hvordan vi kan bruke `map()` med lambda-funksjoner, som er anonyme funksjoner i Python.

Noen ganger trenger vi funksjoner som bare består av én kodelinje, og som kun skal brukes én gang. Disse kan defineres som lambda-funksjoner i Python.

Syntaksen for en lambda-funksjon er: `lambda args: uttrykk`.

#1. Vi ser igjen på listen `strings`. Anta at vi vil ha en liste `strings_rev` som inneholder de omvendte strengene.

strings = ['JavaScript','Rust','Python','Go']

Vi kan snu en Python-streng ved å bruke strengskjæring.

Dette er en generalisering av uttrykket `str[start:stop:step]`.

– Uten start- og stoppverdier starter skiven i begynnelsen av strengen og strekker seg til slutten.
– Negative verdier for `step` gir skiver som starter fra slutten av strengen.
– Derfor vil `str[::-1]` returnere en omvendt kopi av `str`.

Vi kan bruke lambda-funksjonen `lambda x:x[::-1]` inne i `map()`, som vist nedenfor.

strings_rev = list(map(lambda x:x[::-1],strings))
print(strings_rev)

Vi konverterer `map`-objektet til en liste. Utdataene viser at hver streng i `strings` er reversert.

Output
['tpircSavaJ', 'tsuR', 'nohtyP', 'oG']

#2. I forrige seksjon beregnet vi kvadratroten av tallene i en liste og avrundet verdiene til to desimaler.

Vi brukte funksjonen `round_2()` for dette. La oss omskrive `round_2()` som en lambda-funksjon og bruke den med `map()`.

nums_sqrt_round_l =list(map(lambda num:round(num,2),nums_sqrt))
print(nums_sqrt_round_l)

Utdataene er identiske med det vi fikk med `round_2()`.

Output
[5.48, 9.49, 5.83, 6.71, 9.85]

Bruk av `map()` med flere iterables

I eksemplene så langt har vi brukt en funksjon på hvert element i en enkelt samling.

Noen ganger har vi funksjoner som tar to eller flere argumenter. I slike tilfeller lagres hvert argument i en liste eller en lignende samling.

Vi kan bruke `map()` med flere lister.

#1. Se på funksjonen `area()` som tar lengde og bredde som input og returnerer arealet, altså lengde * bredde.

def area(length,breadth):
  return length*breadth

Lengde og bredde til ulike rektangler er lagret i separate lister, `lengths` og `breadths`.

lengths = [4,8,10,18]
breadths = [9,4,6,11]

Vi kan bruke `map()` for å anvende `area()` på listene ved å sende inn både `lengths` og `breadths`.

areas = list(map(area,lengths,breadths))
print(areas)

Siden `area()` tar to argumenter, brukes verdiene fra `lengths` og `breadths` til å beregne arealet.

Output
[36, 32, 60, 198]

#2. Pythons `math`-modul har en logaritmefunksjon som beregner logaritmen til et tall med en gitt base.

Merk: `log(x, base)` returnerer logaritmen av `x` med base `base`, eller logbase(x). Hvis `base` ikke er angitt, er standardverdien e (den naturlige logaritmen).

I dette eksemplet:

  • Listen `x` inneholder verdiene vi vil beregne logaritmen for.
  • Listen `base` inneholder de ulike basene som skal brukes i beregningen.
x = [2,6,12,10]
base = [2,3,2,5]

Vi kan bruke `map()` med `math.log`, listene `x` og `base` for å få en ny liste `log_x`.

log_x = list(map(math.log,x,base))
print(log_x)

Her er utdataene.

Output
[1.0, 1.6309297535714573, 3.5849625007211565, 1.4306765580733933]

Konklusjon

Her er en oppsummering av det vi har lært:

  • Pythons `map()` tar minst to argumenter: en funksjon og en eller flere iterables, med syntaksen `map(funksjon, iterabel(s))`.
  • Funksjonen kan være en hvilken som helst gyldig Python-kallbar.
  • Når funksjonen tar k argumenter, bruker du `map()` med funksjonen og hver av de k argumentene som separate iterables.

Neste steg er å lære mer om mengder (sets) i Python.