This post serves as a refresher and introduces some basic functional programming in Python, as well as an addition to my previous post on the data pipeline. The post material is divided into four parts:
Functional programming principles
The operator
lambda
, functionmap
,filter
,reduce
and others
Inclusion in the sequence
Closure
Functional programming principles
KEY PROVISIONS:
Functional programming is a software writing technique that focuses on functions. Functions can be assigned to variables, they can be passed to other functions and spawned new functions. Python has a rich and powerful arsenal of tools that make it easy to develop function-oriented programs.
In recent years, almost all known procedural and object-oriented programming languages ββhave begun to support functional programming (FP) tools. And Python is no exception.
When talking about FP, they primarily mean the following:
Functions are first-class objects, that is, anything you can do with "data" can also be done with functions (like passing a function to another function as an argument).
. , .
. .
«» . , .
, (.. ). , ( ).
, , .
Β« Β» (, , ).
, . . , , . . , , - . .
, , , . , , . Python , .
.
lambda, map, filter, reduce
, Python. .
lambda
, def
, Python lambda
, -. -:
lambda _:
_ β , , β , . , :
def standard_function(x, y):
return x + y
lambda x, y: x + y
, - , , :
>>> (lambda x, y: x+y)(5, 7)
12
, , , , , , . . ( .)
>>> lambda_function = lambda x, y: x + y
>>> lambda_function(5,7)
12
>>> func = lambda_function
>>> func(3,4)
7
>>> dic = {'1': lambda_function}
>>> dic['1'](7,8)
15
1 - , -. 2 . 4 , . 7 , , , , .
. Python map.
map
, , . . map.
Python map
β , . . map
:
map(, )
β -, β , .. , , .
>>> seq = (1, 2, 3, 4, 5, 6, 7, 8, 9)
>>> seq2 = (5, 6, 7, 8, 9, 0, 3, 2, 1)
>>> result = map(lambda_function, seq, seq2)
>>> result
<map object at 0x000002897F7C5B38>
>>> list(result)
[6, 8, 10, 12, 14, 6, 10, 10, 10]
1 2 , seq seq2, . 3 result map, - . , map - map, 5. - map , , . β , , . , . , , . , . , , «». 6 map .
filter
. filter
, , , , . Python filter
. , . filter
:
filter(_, )
_ β -, , β , .. , , .
, is_even
:
is_even = lambda x: x % 2 == 0
, filter
:
>>> seq = (1, 2, 3, 4, 5, 6, 7, 8, 9)
>>> filtered = filter(is_even, seq)
>>> list(filtered)
[2, 4, 6, 8]
-, :
>>> filtered = iter(filter(lambda x: x % 2 == 0, seq))
>>> list(filtered)
[2, 4, 6, 8]
, filter
-, , . , . , next
.
>>> next(filtered)
2
>>> next(filtered)
4
...
. StopIteration. ,
seq = sequence
try:
total = next(seq)
except StopIteration:
return
reduce
, , , reduce. reduce
functools , , , :
def reduce(fn, seq, initializer=None):
it = iter(seq)
value = next(it) if initializer is None else initializer
for element in it:
value = fn(value, element)
return value
reduce
:
reduce(, , )
β ; -, β , .. , , , β , . β , .. , , .
. , reduce . , :
>>> seq = (1, 2, 3, 4, 5, 6, 7, 8, 9)
>>> get_sum = lambda a, b: a + b
>>> summed_numbers = reduce(get_sum, seq)
>>> summed_numbers
45
. sentences β , , , :
>>> sentences = [".",
>>> ... " , ",
>>> ... " , ."]
>>> wsum = lambda a, sentence: a + len(sentence.split())
>>> number_of_words = reduce(wsum, sentences, 0)
>>> number_of_words
13
-, wsum
, split
, len .
?
.
β -, β .
, , . .
.
for
, . . , , , , . Β« . . Β».
, , . ,
any
,all
.
.
zip
zip
, .. , . zip
:
zip(, , ...)
β , .. , , . zip
-, , . :
>>> x = ''
>>> y = ''
>>> zipped = zip(x, y)
>>> list(zipped)
[('', ''), ('', ''), ('', '')]
*
( , ..) . :
>>> x2, y2 = zip(*zip(x, y))
>>> x2
('', '', '')
>>> y2
('', '', '')
>>> x == ''.join(x2) and y == ''.join(y2)
True
enumerate
enumerate . enumerate:
enumerate()
β , .. , , . enumerate -, , .
, . , .
>>> lazy = enumerate(['','',''])
>>> list(lazy)
[(0, ''), (1, ''), (2, '')]
2 list
, . enumerate :
>>> convert = lambda tup: tup[1].upper() + str(tup[0])
>>> lazy = map(convert, enumerate(['','','']))
>>> list(lazy)
['0', '1', '2']
convert
1 . tup
β , tup[0]
β , tup[1]
β .
, . , Python :
squared_numbers = [x*x for x in numbers]
Python Β« Β» ( . comprehension, ), . . :
[ for in if 2]
β , , β , β , 2 β . , :
>>> numbers = [1, 2, 3, 4, 5]
>>> squared_numbers = [x*x for x in numbers]
>>> squared_numbers
[1, 4, 9, 16, 25]
:
>>> squared_numbers = []
>>> for x in numbers:
>>> squared_numbers.append(x*x)
>>> squared_numbers
[1, 4, 9, 16, 25]
, .. , . , , .
. , . , , Python, Β« Β» , , . , , .
1.
|
|
|
|
|
|
|
|
|
. . β , ( |
, ( ) : , β β .
, map
filter
. , 3 map
:
>>> seq = (1, 2, 3, 4, 5, 6, 7, 8, 9)
>>> seq2 = (5, 6, 7, 8, 9, 0, 3, 2, 1)
>>> result = [x + y for x, y in zip(seq, seq2)]
>>> result
[6, 8, 10, 12, 14, 6, 10, 10, 10]
β , . , zip
, . ( , ..)
filter
:
>>> result = [x for x in seq if is_even(x)]
>>> result
[2, 4, 6, 8]
, . β , .
, . , . . , , «» .
, . . ( , curring) β , . , , adder
:
def adder(n, m):
return n + m
, :
def adder(n):
def fn(m):
return n + m
return fn
-:
adder = lambda n: lambda m: n + m
, -, . adder
. adder(3)
, , . adder
3 3 . :
>>> sum_three = adder(3)
>>> sum_three
<function __main__.<lambda>.<locals>.<lambda>>
>>> sum_three(1)
4
adder(3)
sum_three, . sum_three
, , 3 1.
. . :
def power_generator(base):
return lambda x: pow(x, base)
power_generator
, :
>>> square = power_generator(2) #
>>> square(2)
4
>>> cube = power_generator(3) #
>>> cube(2)
8
, square
cube
base
. power_generator
, , power_generator
. : β , .
. , , , . :
COUNT = 0
def count_add(x):
global COUNT
COUNT += x
return COUNT
, , . , :
def make_adder():
n = 0
def fn(x):
nonlocal n
n += x
return n
return fn
. , nonlocal
, , n fn. , :
>>> my_adder = make_adder()
>>> print(my_adder(5)) # 5
>>> print(my_adder(2)) # 7 (5 + 2)
>>> print(my_adder(3)) # 10 (5 + 2 + 3)
5
7
10
; . , , . . . , , . .