1 2 3 4 5
from itertools import takewhile, countis_small = lambda x: x < 100square = lambda x: x**2small_squared_integers = list(takewhile(is_small, map(square, count(0))))
Fold (også kalt reduce) er en operator som kombinerer en funksjon med en liste elementer. Dette kan brukes til å lage en verdi som "oppsummerer" lista. F.eks. vanlig summasjon i matematikk er en fold:
er (nesten) det samme som foldl (+) 0 [1..10] i språk som Haskell, reduce(+, 1:10) i Julia eller reduce(add, range(1, 10+1), 0) i Python. Nullen i de to uttrykkene betegner start-leddet, dvs. en tom sum er alltid null. Det er likevel en liten forskjell: dette er egentlig en left fold, altså vi antar venstre-assosiativitet, så vi regner egentlig ut
foldl (+) 0 [1..10]
reduce(+, 1:10)
reduce(add, range(1, 10+1), 0)
Men siden addisjon er assosiativ, får vi samme svar. Dette er tanken bak funksjonaliteten til følgende kode
1 2 3 4
from functools import reduceadd = lambda current_sum, next_addend: current_sum + next_addendnumber_sum = reduce(add, range(1, 100+1)) #equivalent to sum(range(1, 100+1))
add-funksjonen kan også importeres fra operator-biblioteket som følger med Python. Her kan det være greit å poengtere at dette kan gjøres med vanlige for-løkker:
add
operator
1 2 3
initial_value = 0for e in range(1, 10+1): initial_value += e
men det ville jo ikke vært like gøy ...
1 2
multiply = lambda current_product, next_factor: current_product*next_factornumber_product = reduce(multiply, range(1, 10+1))
Her kan vi også importere mul fra operator istedenfor å lage denne selv. Python har to andre innebygde funksjoner som er basert på fold-mønsteret. Dette er all og any, som har tilsvarende implementasjon.
mul
all
any
and_ = lambda current_bool, next_bool: current_bool and next_boolnumber_all = reduce(and_, range(1, 10+1)) #equivalent to all(range(1, 10+1))
or_ = lambda current_bool, next_bool: current_bool or next_boolnumber_all = reduce(or_, range(1, 10+1)) #equivalent to any(range(1, 10+1))
Med matematisk terminologi har vi en binær funksjon f ( a , b ) og en (endelig) ordnet liste ( x i ) (samt en mulig startverdi s 0 ). En venstrefold blir da
En høyrefold blir tilsvarende
filter er en funksjon som filtrerer ut elementer ut ifra ett sannhets-kriterie. Den tar inn en unær boolsk funksjon og en liste.
filter
is_odd = lambda x: x%2for i in filter(is_odd, range(10)): print(i, end=' ')#1 3 5 7 9
Igjen, dette kan også skrives med vanlige for-løkker og if-setninger
1 2 3 4 5 6
is_odd = lambda x: x%2for i in range(10): if is_odd(i): print(i, end=' ')#1 3 5 7 9
Men fordi vi bare bruker oddetall i løkka, kan det være greit å filtrere bort partallene fra lista, istedenfor å sjekke dette i løkka.
Det var alt for denne gang. Nå blir det nok 4 måneder til neste blogginnlegg.