Higher-order function
- Variables can point to functions, that is, functions themselves can also be assigned to variables.
- The function name is also a variable.
- Functions are passed in as parameters. Such functions are called higher-order functions.
map/reduce
-
The map() function receives two parameters, one is a function and the other is Iterable. The map functions the incoming function into each element of the sequence in turn, and returns the result as a new Iterator.
<<< def f(x): return x * x <<< r = map(f, [1, 2, 3, 4, 5, 6, 7, 8, 9]) <<< list(r) [1, 4, 9, 16, 25, 36, 49, 64, 81] # The first parameter passed in by map() is f, the function object itself. # Because the result r is an Iterator, Iterator is an inert sequence. # So the whole sequence is computed by the list() function and a list is returned.
-
reduce() function.
reduce(f, [x1, x2, x3, x4]) = f(f(f(x1, x2), x3), x4) # f is two parameters reduce(f, [x1, x2, x3, x4]) = f(f(f(f(x1), x2), x3), x4) # f is a parameter
# Functions converted from str to int from functools import reduce def str2int(s): def fn(x, y): return x * 10 + y def char2num(s): return {'0':0, '1':1, '2':2, '3',3, '4':4, '5':5, '6':6, '7':7, '8':8, '9':9}[s] return reduce(fn, map(char2num, s))
# str2float CHAR_TO_FLOAT = { '0': 0, '1': 1, '2': 2, '3': 3, '4': 4, '5': 5, '6': 6, '7': 7, '8': 8, '9': 9, '.': -1 } def str2float(s): nums = map(lamba ch: CHAR_TO_FLOAT[ch], s) point = 0 def to_float(f, n): nonlocal point if n == -1: point = 1 return f if point == 0: return f * 10 + n else: point = point * 10 return f + n /point return reduce(to_float, num, 0.0)
filter
- filter() acts on each element in turn, and then decides whether to retain or discard the element based on whether the return value is True or False.
-
The filter() function returns an Iterator, requiring a list() function to get all the results and return a list.
# In a list, delete even numbers and keep only odd numbers def is_odd(n): return n % 2 == 1 list(filter(is_odd,[1, 2, 3, 4, 5, 6, 9]))
# Delete empty strings from a sequence def not_empty(s): return s and s.strip() list(filter(not_empty, ['A', '', 'B', None, 'C', ' ']))
#!/usr/bin/env python3 # -*- coding: utf-8 -*- # Using filter to find prime numbers def main(): for n in primes(): if n < 1000: print(n) else: break # Construct an odd sequence starting from 3. Note that this is a generator and an infinite sequence. def _odd_iter(): n = 1 while True: n = n + 2 yield n # Define filter function def _not_divisible(n): return lambda x: x % n > 0 # Define the generator and keep returning to the next prime def primes(): yield 2 it = _odd_iter() # Initial sequence while True: n = next(it) # The next number of returned sequences yield n it = filter(_not_divisible(n), it) # Constructing New Sequences if __name__ == '__main__': main()
sorted
- Sort the strings, ignore case, sort them alphabetically, and pass the key function to sorted.
sorted(['bob', 'about', 'Zoo', 'Credit'], key = str.lower)
-
For reverse sorting, you can pass in the third parameter reverse=True
from operator import itemgetter students = [('Bob', 75), ('Adam', 92), ('Bart', 66), ('Lisa', 88)] print(sorted(students, key = itemgetter(0))) print(sorted(students key = lambda t: t[1])) print(sorted(students, key = itemgetter(1), reverse = True))
Return function
- Function as return value
def lazy_sum(*args):
def sum():
ax = 0
for n in args:
ax = ax + n
return ax
return sum
<<< f1 = lazy_sum(1, 3, 5, 7, 9)
<<< f2 = lazy_sum(1, 3, 5, 7, 9)
<<< f1 == f2
False
- Closure. The returned function is not executed immediately. The returned function does not refer to loop variables or variables that will change later.
Anonymous function
- Anonymous functions can only have one expression, without writing return, the return value is the result of the expression. Anonymous function is also a function object, which can be assigned to a variable and then called by variables.
<<< list(map(lambda x: x * x), [1, 2, 3, 4, 5, 6, 7, 8, 9])
# The keyword lambda denotes anonymous functions, and the x before the colon denotes function parameters.
Decorator
-
Decorator, add function dynamically during code running.
import functools def log(func): @functools.wraps(func) def wrapper(*args, **kw): print('call %s():' % func.__name__) return func(*args, **kw) return wrapper @log def now(): print('2015-3-25') <<< now() # now = log(now) call now(): 2015-3-25
import functools def log(text): def decorator(func): @functools.wrap(func) def wropper(*args, **kw): print('%s %s' % (text, func.__name__)) return func(*args, **kw) return wrapper return decorator @log('execute') def now(): print('2015-3-25') <<< now() # now = log('execute')(now) execute now(): 2015-3-25 <<< now.__name__ 'wrapper'
Partial function
-
functools.partial. When creating a partial function, you can actually accept three parameters: function object, * args and ** kw.
def int2(x, base = 2): return int(x, base)
<<< import functools <<< int2 = functools.partial(int, base = 2)