This is the 22nd day of my participation in Gwen Challenge

Functional programming

One of the great things about functional programming is that you can pass a function as an argument to another function, and you can return a function! Python provides partial support for functional programming. Because Python allows the use of variables, Python is not a purely functional programming language

Higher-order functions

Features:

  1. A variable can either point to a function itself or it can be assigned to a variable x=abs x(-10) #10

  2. Abs = 10 abs(-10) # TypeError: ‘int’ object is not callable

    Note: Since the ABS function is actually defined in the import Builtins module, to change the reference of the ABS variable to take effect in other modules, use import Builtins; builtins.abs = 10

  3. The incoming function

    Since variables can point to functions and arguments to functions can accept variables, a function can accept arguments to another function, which is called a higher-order function

    def add(x, y, f) :
        return f(x) + f(y)
    print(add(-5.6.abs))    
    # 11   
    Copy the code

Map/reduce, filter, sorted

Map/Reduce Concepts: Google paper “MapReduce: Simplified Data Processing on Large Clusters”

These four uses are the same as es6.

  1. The map() function takes two arguments, a function and an Iterable that returns an Iterator

    def f(x) :
        return x**2
    a=map(f,[x for x in range(10)])
    print(next(a)) # 0
    print(list(a)) # [1, 4, 9, 16, 25, 36, 49, 64, 81]
    Copy the code

    Convert all the numbers in this list to strings:

    print(list(map(str[1.2.3.4.5.6.7.8.9)))# ['1', '2', '3', '4', '5', '6', '7', '8', '9']
    Copy the code
  2. Reduce () continues the cumulative calculation with the next element of the sequence :reduce(f, [x1, x2, x3, x4]) = f(f(f(x1, x2), x3), x4) sequence [1, 3, 5, 7, 9] transforms to the integer 13579:

    from functools import reduce
        def fn(x,y) :
            return x*10+y
        print(reduce(fn,[1.3.5.7.9])) # 13579
    Copy the code

    STR converts to int:

    from functools import reduce
    
    DIGITS = {'0': 0.'1': 1.'2': 2.'3': 3.'4': 4.'5': 5.'6': 6.'7': 7.'8': 8.'9': 9}
    
    def char2num(s) :
        return DIGITS[s]
    
    def str2int(s) :
        return reduce(lambda x, y: x * 10 + y, map(char2num, s))
    print(str2int('0123456789'))     # 123456789
    Copy the code
  3. Filter () takes a function and a sequence, and returns an Iterator that filters out the numbers that match the criteria

    def is_odd(n) :
    return n % 2= =1
    list(filter(is_odd, [1.2.4.5.6.9.10.15]))
    Copy the code
  4. Sorted () receives a sequence and a function sorted([36, 5, -12, 9, -21]) by absolute size:

    sorted([36.5, -12.9, -21], key=abs)
    # [5, 9, -12, -21, 36]
    Copy the code

    To reverse sort, without changing the key function, we can pass a third parameter reverse=True:

    L = [('Bob'.75), ('Adam'.92), ('Bart'.66), ('Lisa'.88)]
    def by_name(t) :
        return t[0]
    L2 = sorted(L, key=by_name,reverse=True)
    print(L2)    
    Copy the code

Returns the function

Function as the return value

In addition to accepting functions as arguments, higher-order functions can also return functions as result values.

Variable argument summation (returns the result immediately):

def calc_sum(*args) :
    ax = 0
    for n in args:
        ax = ax + n
    return ax
Copy the code

The function that returns the sum:

def lazy_sum(*args) :
    def sum() :
        ax = 0
        for n in args:
            ax = ax + n
        return ax
    return sum
f = lazy_sum(1.3.5.7.9)
f() # 25
Copy the code

Closures (note!)

One thing to keep in mind when returning closures is that the return function should not reference any loop variables, or variables that will change later.

def count() :
    fs = []
    for i in range(1.4) :def f() :
             return i*i
        fs.append(f)
    return fs

f1, f2, f3 = count() 
# f1() 9
# f2() 9
# f3() 9
# All nines! The reason is that the returned function refers to variable I, but it is not executed immediately. By the time all three functions return, the variable I referenced by them has changed to 3, so the final result is 9.
Copy the code
def count() :
    def f(j) :
        def g() :
            return j*j
        return g
    fs = []
    for i in range(1.4):
        fs.append(f(i)) # f(I) is executed immediately, so the current value of I is passed into f().
    return fs
for fn in count():
    print(fn())
4 and 9 # 1
Copy the code

Anonymous functions

The lambda keyword stands for anonymous functions, and the x before the colon stands for function arguments. List (map(lambda x: x * x, [1, 2, 3, 4, 5, 6, 7, 8, 9]))

lambda x: x * x  # is equal to the
def f(x) :
    return x * x
Copy the code

One advantage of using anonymous functions is that they don’t have names, so you don’t have to worry about function name conflicts. In addition, an anonymous function is also a function object. It is also possible to assign an anonymous function to a variable and use the variable to call the function:

Assign an anonymous function to a variable and use the variable to call the function
f = lambda x: x * x
f(5)
# 25
The anonymous function is returned as a return value
def build(x, y) :
    return lambda: x * x + y * y
Copy the code

A decorator

In essence, a Decorator is a higher-order function that returns a function

Take a look at the following code and it becomes immediately clear that this is the idea of Spring AOP, which feels like Java annotations

@log
def now(a,b,*,age) :
    print('2015-3-25')

def log(func) :
    def wrapper(*args, **kw) :
        print('call %s():' % func.__name__) # __name__ Gets the function object's name
        print( args)
        print( kw)
        return func(*args, **kw)
    return wrapper

now('1'.'1',age=12)
# call now():
# (' 1 ', '1')
# {'age': 12}
# 2015-3-25
Copy the code

Now = log(now) wrapper() is defined as (*args, **kw), so the Wrapper () function can be called with any argument. Inside the Wrapper () function, the log is first printed and then the original function is called.

def log(text) :
    def decorator(func) :
        def wrapper(*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()
# execute now():
# 2015-3-25
Copy the code

Now = log(‘execute’)(now) executes log(‘execute’), returns a decorator function, and calls the returned function with the argument now and return the wrapper function. Functions are also objects that have attributes like __name__ so you end up with now.__name__ #’wrapper’ which can cause some code execution errors that rely on function signatures

But the built-in Functools. wraps is used to copy attributes like __name__ of the original function into the corresponding function, as in:

@functools.wraps(func)
    def wrapper(*args, **kw) :
Copy the code

Run now.__name__ after modification. The results for # now

Partial function

Partial functions are functions with fixed arguments, that is, functions with default values

Python’s Functools module provides many useful functions. One of them is a Partial function,

Functools. partial creates a partial function that fixes the parameters of a function and returns a new function that accepts the function object, *args, and **kw

Such as the int function

import functools
int2 = functools.partial(int, base=2)
int2('1000000')
# 64
Copy the code

Such as Max function

import functools
# will actually automatically add 10 as part of *args to the left side √ (~ ▽ ~ /$:*)
max2 = functools.partial(max.10)
max2(5.6.7)
# 10
Copy the code

The last

Welcome friends to discuss the question ~

If you think this article is good, please give it a thumbs-up 😝

Let’s start this unexpected meeting! ~

Welcome to leave a message! Thanks for your support! ヾ(≧▽≦*)o go!!

I’m 4ye. We should… next time. See you soon!! 😆