"Python" "Functional Programming"

Source: Internet
Author: User
Tags abs closure

# "Functional Programming" "
"""
function is a kind of encapsulation supported by Python, we can decompose complex tasks into simple tasks by splitting large pieces of code into functions through a layer of function calls, which can be called process-oriented programming. function is the basic unit of process-oriented program design.

and functional programming (note that more than one "type" word)--functional programming, although it can also be attributed to the process-oriented programming, but the idea is closer to the mathematical calculation.

We first have to understand the concepts of computer (computer) and computational (Compute).

At the level of the computer, the CPU executes the subtraction instruction code, as well as various conditional judgments and jump instructions, so, assembly language is the most close to the computer languages.

And the calculation of the exponential meaning, the more abstract calculation, the farther away from the computer hardware.

corresponding to the programming language, is the lower level of the language, the more close to the computer, low degree of abstraction, implementation of high efficiency, such as C language, the more advanced language, the more close to the computation, high degree of abstraction, inefficient execution, such as Lisp language.

Functional programming is a very high degree of abstraction of the programming paradigm, the purely functional programming language functions are not variable, so any function, as long as the input is determined, the output is OK, this pure function we call no side effects. In the case of programming languages that allow the use of variables, because of the variable state inside the function, the same input may get different output, so this function has side effects.

One of the features of functional programming is that it allows the function itself to be passed as a parameter to another function, and also allows a function to be returned!

Python provides partial support for functional programming. Because Python allows the use of variables, Python is not a purely functional programming language.
"""
# "Higher order Function"

#变量可以指向函数
Print (ABS (-10))
Print (ABS) #<built-in function abs>


def add (x,y,f):
return f (x) + f (Y)
x =-5
y = 6
F = ABS
Print (Add (x,y,f)) #11

# "Higher order Function" "Map"
def f (x):
return x * x
R = Map (f,[1,2,3,4,5])
Print (list (r)) #[1, 4, 9, 16, 25]
Print (R) #<map object at 0x1022454a8>
#一行代码就是
Print (List (map (f,[1,2,3,4))) #[1, 4, 9, 16, 25]

# "Higher order Function" "Reduce"
From Functools import reduce
def add (x, y):
return x + y
R = Reduce (add,[1,2,3,4])
Print (R) #10
#当然, the sum operation can also be built with Python to sum the function, no need to use reduce.
#但是, if you want to turn the sequence [1,3,5,7,9] into an integer 13579,reduce it will come in handy.
From Functools import reduce
DEF fn (x, y):
return * x + y
Print (Reduce (fn,[1,3,5,7,9)) #13579

# str 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, "0": 0}

def str2int (s):
DEF fn (x, y):
return * x + y
def char2num (ss):
return DIGITS[SS]
return reduce (Fn,map (char2num,s))
Print (Str2Int ("13579")) #13579

# You can also use lambda functions to further simplify
def str2int (s):
return reduce (lambda x,y:10 * x + y,map (lambda a:digits[a],s))
Print (Str2Int ("2468")) #2468

# exercise 1: Use the map function, the user entered the non-standard English name, the first letter capitalized, the other lowercase canonical name.
def nomalize (name):
Return Name.capitalize ()
L1 = ["Adam", "LISA", "BarT"]
L2 = List (map (NOMALIZE,L1))
Print (L2) #[' Adam ', ' Lisa ', ' Bart '

#练习2: the sum () function provided by Python can receive a list and sum. Write a prod () function that receives a list and uses the reduce to calculate the product
def prod (L):
return reduce (lambda x,y:x * y,l)
Print (' 1*3*5*4= ', prod ([1,3,5,4]))
If prod ([1,3,5,4]) = = 60:
Print ("Test succeeded! ")
Else
Print ("Test failed! ")
‘‘‘
1*3*5*4= 60
Test success!
‘‘‘
#练习3: Use map reduce to write str2float, turn the string "123.456" into a floating point number 123.456
#方法1 I wrote it myself.
From Functools import reduce
def STR2FLOAT1 (s):
digits = {"1": 1, "2": 2, "3": 3, "4": 4, "5": 5, "6": 6, "7": 7, "8": 8, "9": 9, "0": 0}
DEF fn (x, y):
return * x + y
def char2num (s):
return Digits[s]
return reduce (Fn,map (Char2num,s.split (".") [0]) + reduce (Fn,map (Char2num,s.split (".") [1])) /10**len (S.split (".") [1])
Print (' Str2float1 (\ ' 123,456\ ') = ', Str2float1 (' 123.456 '))
If STR2FLOAT1 (' 123.456 ') = = 123.456:
Print (' Test succeeded! ‘)
Else
Print (' Test failed! ‘)
‘‘‘
STR2FLOAT1 (' 123,456 ') = 123.456
Test success!
‘‘‘

# method 2: Online, relatively concise
From Functools import reduce
def STR2FLOAT2 (s):
DEF fn (x, y):
return 10*x + y
n = S.index (".")
S1 = List (map (int,s[:n))
S2 = List (Map (int,s[n+1:]))
return reduce (FN,S1) + reduce (fn,s2)/10**len (S2)
Print (' Str2float (\ ' 789.123\ ') = ', Str2float2 (' 789.123 '))
If Str2float2 (' 789.1234 ') = = 789.1234:
Print (' Test succeeded! ‘)
Else
Print (' Test failed! ‘)
‘‘‘
Str2float (' 789.123 ') = 789.123
Test success!
‘‘‘

# "Higher order Function" "Filter"
# and & OR
Print (0 or 1) #1
Print (1 or 0) #1
Print (False or True) #True
Print (True or 0) #True
Print (False or 0) #0
Print (' *********** ')
Print (0 and 1) #0
Print (1 and 3) #3
Print (1 and 0) #0
Print (True and False) #False
Print (False and 7) #False
Print (1 and 7) #7
Print (None and None.strip ()) #None

# Delete the empty string from a sequence
def not_empty (s):
return s and S.strip ()
Print (List (filter (not_empty,[' A ', ' ', ' B ', None, ' C ', '])))) #[' A ', ' B ', ' C ']

# Use filter to calculate prime numbers
‘‘‘
Analysis
One way to calculate prime numbers is through the method of the Fourier sieve, which is very simple to understand:
First, list all the natural numbers starting with 2, and construct a sequence:
2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, ...
Take the first number of the sequence 2, it must be a prime, and then sift out the multiples of 2 of the sequence with 2:
3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, ...
Take the first number of a new sequence of 3, it must be a prime, and then sift out the multiples of 3 of the sequence 3:
5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, ...
Take the first number of the new sequence 5, and then sift out the multiples of 5 of the sequence with 5:
7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, ...
Keep sifting down and you can get all the primes.
‘‘‘
# three steps. 1 first constructs a 3 odd series 2 defines a filter function 3 defines a generator that continuously returns the next prime number
Def _odd_iter ():
n = 1
While True:
n = n + 2
Yield n

def _not_divisible (n):
Return lambda x:x%n > 0

Def primes ():
Yield 2
it = _odd_iter () # Initial sequence
While True:
n = Next (IT)
Yield n
it = filter (_not_divisible (n), it)

# because Primes () is also an infinite sequence, you need to set a condition to exit the loop when calling:
For n in primes ():
If n < 10:
Print (n)
Else
Break
‘‘‘
2
3
5
7
‘‘‘

# Practice back numbers are the same number from left to right and from right to left. Filter the number of returns using filter ()
Output = List (filter (lambda n:str (n) [0:] = = str (n) [:: -1],range (1,100))]
Print (output)
if output = = [1,2,3,4,5,6,7,8,9,11,22,33,44,55,66,77,88,99]:
Print (' Test succeeded! ‘)
Else
Print (' Test failed! ‘)


# "Higher order Function" "sorted"
Print (sorted ([36,5,-12,9,-21])) #[-21,-12, 5, 9, 36]
Print (sorted ([36,5,-12,9,-21],key=abs)) #[5, 9,-12,-21, 36]
Print (sorted ([' Bob ', ' about ', ' zoo ', ' credits ')]) #[' credits ', ' Zoo ', ' about ', ' Bob ', ' remarks ' string sort by default according to a Scii size, because uppercase letters precede lowercase letters
#如果想忽略大小写
Print ([' Bob ', ' about ', ' zoo ', ' credits '],key=str.lower) #[' about ', ' Bob ', ' credits ', ' Zoo ']
#用大写函数同样适用
Print ([' Bob ', ' about ', ' zoo ', ' credits '],key=str.upper) #[' about ', ' Bob ', ' credits ', ' Zoo ']
#反向排序
Print (sorted ([' Bob ', ' about ', ' zoo ', '],key=str.upper,reverse=true ')) #[' Zoo ', ' credits ', ' Bob ', ' about ']

# Practice: Use a group of tuples to represent student names and grades
L = [(' Bob ', ', '), (' Adam ', ' the '), (' Bart ', ' the '), (' Lisa ', 88)]
#请用sorted对上述列表分别按照名字和成绩排序
def by_name (t):
Return T[0].lower ()
def by_score (t):
return t[1]
Print (' Sort results by name: ', Sorted (l,key=by_name)) #按照名字排序结果: [(' Adam ', ' the '), (' Bart ', ' the '), (' Bob ', '), (' Lisa ', 88)]
Print (' Results sorted by score: ', Sorted (l,key=by_score) ') #按照成绩排序结果: [(' Bart ', ' $92 '), (' Bob ', '), (' Lisa ', ' a ', ') '

# "Functional Programming" "Return function"
#函数作为返回值
#实现一个可变参数的求和. Typically, the SUM function defines this
def calc_sum (*args):
Ax = 0
For n in args:
AX = ax + N
return ax
#但是, if you do not need to sum immediately, but back, and then calculate as needed. Instead of returning the sum result directly, the SUM function is returned.
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)
Print (f) #<function lazy_sum.<locals>.sum at 0x101a5a048>
Print (f ()) #25
# "Note" Every Time Lazy_sum () is called, a new function is returned, even if the same parameters are passed in
F1 = Lazy_sum (1,3,5)
F2 = Lazy_sum (1,3,5)
Print (f1 = = F2) #False F1 () F2 () call results do not affect each other

# Closed Bag
def count ():
FS = []
For I in Range (1,4):
def f ():
return I * I
Fs.append (f)
Return FS
F1,F2,F3 = count ()
Print (F1 ())
Print (F2 ())
Print (F3 ())
‘‘‘
9
9
9
All is 9, because the function returned refers to the variable I, but it is not immediately executed. When all three functions return, they refer to a variable that has been programmed by 3, so the end result is 9.
‘‘‘
# "Note" Return closure keep in mind that the return function does not reference any of the loop variables, or subsequent variables that change
#如果一定要引用循环变量, you can create a function that binds the current value of the loop variable with the parameter of the function, regardless of how the loop variable is subsequently modified, the value that is bound to the function parameter is not changed.
Def count2 ():
def f (j):
def g ():
Return J * J
Return g
FS = []
For I in Range (1,4):
Fs.append (f (i))
Return FS
F1,F2,F3 = Count2 ()
Print (F1 ())
Print (F2 ())
Print (F3 ())

‘‘‘
1
4
9
‘‘‘
# The variable within the method, until the method frame has not finished, has been valid "remarks" I do not know this is the right ... It's just a way for me to understand that. Just like
Import time
def now ():
Timel = []
time1 = Time.time ()
Time2 = time1 + 1000
Time3 = time2 + 1000
Timel.append (TIME1)
Timel.append (time2)
Timel.append (Time3)
def g (x):
return Timel[x]
Return g
bb = Now ()
For I in Range (0,3):
Print (BB (i))
‘‘‘
1531637726.270685
1531638726.270685
1531639726.270685
‘‘‘

#练习: Returns a function with a closure that returns an incremented integer each time it is called
#方法1
Def createcounter ():
A = [0]
Def counter ():
A[0] = a[0] + 1
return a[0]
Return counter
Createra = Createcounter ()
Print (Createra (), Createra (), Createra ())
#方法2
A = 0
Def createCounter2 ():
Def counter ():
Global A
A = a + 1
Return a
Return counter
Createrb = CreateCounter2 ()
Print (Createrb (), Createrb (), Createrb ())


# "Decorator"
def now ():
Print (' 2018-07-15 ')
f = Now
Print (now.__name__) #now
Print (f.__name__) #now

# Two layers of nesting
‘‘‘
Now, let's say that you want to enhance the functionality of the current () function, for example, to automatically print the log before and after a function call, but you don't want to modify the definition of the now () function, which dynamically adds functionality during code run
, called the "Adorner" (Decorator).
Essentially, decorator is a higher-order function that returns a function.
‘‘‘
def log (func):
def wrapper (*args,**kwargs):
Print (' Call%s (): '%func.__name__)
return func (*args,**kwargs)
Return wrapper
@log
def now ():
Print (' 2018-07-15 ')
Now ()
Print (now.__name__)
‘‘‘
Call Now ():
2018-07-15
Wrapper
‘‘‘

‘‘‘
Put the @log at the definition of the now () function, equivalent to execute now = log (now), because log () is a decorator, return a function, the original now () function still exists, just
Now the name of the current variable is pointing to the new function, and calling
‘‘‘
#decorator本身需要传入参数.
def log (text):
def decorator (func):
def wrapper (*args,**kwargs):
Print ('%s%s (): '% (text,func.__name__))
Func (*args,**kwargs)
Return wrapper
return decorator
@log (' Execute ')
def now ():
Print (' 2018-07-15 ')
Now ()
# "Parse" equivalent to define now = log (' Execute ') (now)

#经过decorator装饰的函数, the name will be programmed wrapper, in order to avoid the code execution error since the function signed, do not need to write wrapper.__name__ = func.__name__, Python's built-in Functools.wraps is doing this. So, a complete decorator is as follows.
Import Functools

def log (func):
@functools. Wraps (func)
def wrapper (*args,**kwargs):
Print (' Call%s (): '% func.__name__)
return func (*args,**kwargs)
Return wrapper

#或者带参数的decorator
Import Functools
def log (text):
def decorator (func):
@functools. Wraps (func)
def wrapper (*args,**kwargs):
Print ('%s%s (): '% (text,func.__name__))
return func (*args,**kwargs)
Return wrapper
return Decorator ()

#练习 design a decorator that can be used on any function and print the execution time of the function.
Import Time,functools
def printcalltime (func):
@functools. Wraps (func)
def wrapper (*args,**kwargs):
Start = Time.time ()
res = func (*args,**kwargs)
End = Time.time ()
Print ('%s Execute time =%s ms '% (func.__name__, (End-start) *1000))
return res
Return wrapper

@printcalltime
Def print1 ():
Time.sleep (1)
Print (1)

Print1 ()
Print (print1.__name__)
‘‘‘
1
Print1 Execute time = 1002.7890205383301 ms
Print1
‘‘‘

# Practice
‘‘‘
Write a @log decorator so that it supports both:

@log
def f ():
Pass

also supports:

@log (' Execute ')
def f ():
Pass
‘‘‘
def log2 (text):
If callable (text) = = False:
def decorator (func):
@functools. Wraps (func)
def wrapper (*args, **kwargs):
Print (' Execute%s for%s '% (text,func.__name__))
return func (*args,**kwargs)
Return wrapper
return decorator
Else
@functools. Wraps (text)
def wrapper (*args,**kwargs):
Return text (*args,**kwargs)
Return wrapper
@log2
Def now1 ():
Print ("Hello Now1")

@log2 (' Too late ')
Def now2 ():
Print ("Hello Now2")

Now1 ()
Now2 ()
‘‘‘
Hello Now1
Execute too late for Now2
Hello Now2
‘‘‘

# "Partial function"
#int函数, the default is 10 binary.
print (int (' 12345 ')) #12345
#int函数还提供base参数, the default is 10, and if passed in, it is converted according to the parameter's binary
print (int (' 12345 ', base=8)) #5349
print (int (' 12345 ', 8)) #5349
print (int (' One ', base=2)) #3
#假设要大量转换二进制字符串, it is too troublesome to pass in Int (x,base=2) every time, so I think of defining a int2 () function, by default base=2 it in.
def int2 (x,base=2):
return int (x,base)
#functools. Partial is the creation of partial functions, which do not need to be defined by themselves Int2 ()
Import Functools
Int2 = functools.partial (int,base=2)
Print (Int2 (')) #4
Print (Int2 (' 101 ')) #5
‘‘‘
When you create a partial function, you can actually receive the 3 parameters of the function object, *args, and **kw when passed in:

Int2 = functools.partial (int, base=2)
The keyword parameter base of the int () function is actually fixed, i.e.:

Int2 (' 10010 ')
Equivalent:

KW = {' base ': 2}
Int (' 10010 ', **kw)
When incoming:

Max2 = Functools.partial (max, 10)
Will actually automatically add 10 as part of the *args to the left, namely:

MAX2 (5, 6, 7)
Equivalent:

args = (10, 5, 6, 7)
Max (*args)
The result is 10.
‘‘‘























"Python" "Functional Programming"

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.