[the strongest in the whole network] python function

Keywords: Python Back-end

  Welcome to the column [the strongest in the whole network] Python system learning manual

catalogue

1, Introduction to functions

2, Parameters of function

3, Local function (nesting of functions)

4, Advanced content of functions

5, Local functions and lambda  

1, Introduction to functions

1. Concept

  • Functions are code fragments that can repeatedly perform certain tasks, with independent fixed input and output interfaces.
  • The essence of function definition is to give a piece of code a name for easy reuse in the future
  • In order to facilitate calling this function later, when defining it, it is necessary to specify its input (parameters) and output (return value).

2. Define the syntax format of the function

def Function name(parameter list ):
    #Executable statement
    return Return value

Function name

  • As long as it is a legal identifier (the same as variable naming)
  • To improve readability, it is recommended that the function name be composed of one or more meaningful words, underlined between words_ Separate, all lowercase letters

parameter list

  • In the parentheses after the function name, multiple formal parameters are separated by commas, and there can be no parameters
  • Parameters can have default values. You can directly specify the default value with the equal sign =. Parameters with default values must rank last
  • Parameters without default values must be specified when calling
  • Formal parameters can also be absent, but parentheses cannot be omitted
  • Specify a name when calling a parameter with a default value

Return value

  • The return value can be zero, and the sentence return is omitted directly
  • The return value can be one or more, separated by commas and combined into a tuple
  • The return value can also be an expression
  • Multiple return values. Replace unnecessary ones with underscores!

3. Function documentation (comment → help)

  • An annotated text explains the function.
  • You can use help() to view the documentation of the function. As long as you put a string immediately after the declaration line of the function, it can be recognized by help.

4. Examples

# Function definition
def myfunc(arg1, arg2, arg3=None):
    ''' 
    This is a example for python documentation.
    This is a python Function provides an example of a document.
    arg1: Description of the first parameter
    arg2: Description of the second parameter
    arg3: Description of the third parameter (this parameter has a default value)
    v1, v2, v3: Description of the return value 
    '''
    v1 = arg1 + arg2
    v2 = arg1 * arg2
    if arg3 is None:
        v3 = arg1 + arg2
    else:
        v3 = arg1 + arg2 + arg3
    return v1, v2, v3
# function call
v1, v2, v3 = myfunc(5, 3, arg3=4)
print(v1, v2, v3)    #8 15 12

# Call the function with the default value of arg3
v1, v2, v3 = myfunc(5, 3)
print(v1, v2, v3)    #8 15 8

# Ignore a return value
v1, v2, _ = myfunc(5, 3)
print(v1, v2, v3)    #8 15 8

# The returned value is tuple, which is automatically unpacked during the return process
print(type(myfunc(5,3)))    #<class 'tuple'>

2, Parameters of function

  • The parameters of a function are the channels through which the parameters interact with external variable inputs.
  • The parameter name of the function shall meet the identifier naming specification and have clear meaning. The meaning of each parameter can be known through the parameter name.
  • Note the meaning of the function (and return value) one by one in the comments below the function definition, so that users can use it correctly even if they don't know the specific contents of the function.
  • Argument: actual parameter, the actual parameter passed from outside
  • Formal parameter: formal parameter, its formal name inside the function
  • When a function is called, the argument is bound to the formal parameter according to the sequence position, which is called the Positional Argument
  • You can also specify the corresponding relationship between the actual participating formal parameters during the call, which is called Keyword Argument. At this time, the location information is ignored
  • When passing location parameters and keyword parameters at the same time, you should pass location parameters first and then keyword parameters!
  • When defining a function, you can specify a default value, but the parameters with default values must be listed at the end of the parameter list
#Take a small chestnut and calculate the volume of the paper box
def cube_volume(length, width, height = 0.25):
    '''
    Calculate the volume of the paper box(Company: m)
    length: Long;    width: wide
    height: High (default parameter 0).25)
    v: Return value, carton volume, unit m**3
    '''
    if length <= 0:
        print('length must larger than 0!')
        return 0
    if width <= 0:
        print('width must larger than 0!')
        return 0
    if height <= 0:
        print('height must larger than 0!')
        return 0
    v = length*width*height
    print('length = %.2f; width = %.2f; height = %.2f; cube volume = %.2f' % \
          (length, width, height, v))
    return v

# Call with positional parameters
v = cube_volume(1, 2, 3)
# Call with keyword parameters
v = cube_volume(width = 1, height = 2, length = 3)
# Mixed use of location parameters and keyword parameters
v = cube_volume(1, height = 2, width = 3)

# The keyword parameter will report an error before the location parameter
# v = cube_volume(width = 1, 2, 3)

1. Variable object

  • If the parameter is a variable object (such as a list), the modification of this object within the function will still be valid after the function is executed
  • If the default parameter is a variable object, the default value of the function changes after the object is modified inside the function!
  • The actual function passes in the address. The function body will not pass out the address, but the value corresponding to the address has changed.
# Power operation on list
def pow_list(x, p):
    '''
    power of a list
    x: list
    p: power
    not return value
    '''
    for i in range(len(x)):
        x[i] **= p
    
    #This will output the value after power, but will not change the value in the x list
    #Because the value in x is passed into a new parameter for calculation
    #for i in x:
    #    i **= p
    #    print(i)
    #print(x)

x = [1,2,3,5,7,9,10,12]
pow_list(x,2)
print(x)
# It can be seen that the internal changes of the function to the elements in the list x are still valid after the function exits

Using the characteristics of variable objects, a hidden parameter recorder can be made 👇

# Hidden parameter recorder
def growing_list(x, y=[]):
    y.append(x)
    print(y)
# What happens when the growing_list('a ') is executed repeatedly?
growing_list(2)         #[2]
growing_list('Zhang San')    #[2, 'Zhang San']
growing_list(22333)     #[2, 'Zhang San', 22333]

2. Parameter collection (variable number of parameters)

  • Parameter collection specifies that an indefinite number of parameters can be passed to the function, for example, sometimes 3, sometimes 5, sometimes 10, and so on.
  • When passing an indefinite number of parameters, an asterisk "*" shall be added when defining the parameters (tuple with empty formal parameters).
  • Parameters with an asterisk can be anywhere in the parameter list (not necessarily the beginning or the end). python requires that a function can only have one parameter with an asterisk.
# Summation of indefinite numbers
def my_sum(*t):
    # Input parameters with asterisks are treated as tuples
    print(t, type(t))
    sum = 0
    for s in t:
        sum += s
    return sum
# In fact, the function accepts an indefinite number of input parameters
my_sum(1,2,3,4,2233)
  • If there are other parameters after the star parameter, they must be passed in the form of keyword parameters, otherwise python will collect them into the star parameter if it doesn't know what they are.

# Sum after multiplication of indefinite numbers
def pow_sum(*t, p):
    # Input parameters with asterisks are treated as tuples
    print(t, type(t))
    sum = 0
    for s in t:
        sum += s**p
    return sum
# For the last parameter p, you need to specify keyword transfer
pow_sum(1,2,3,4,2233,p=2)
# If the keyword is not specified, an error will be reported
# pow_sum(1,2,3,4,2233,2)

3. Solve a practical problem

# Numerical weighted summation of indefinite numbers
# The weight changes with the number of numbers
def weighted_sum(x1,x2,*y):
    sum = 0
    n = len(y)
    weight = 1/3/n
    for i in y:
        sum += weight*i
    return sum+1/3*x1+1/3*x2

weighted_sum(1,2,3)
weighted_sum(1,2,3,22,44,55)
weighted_sum(1,2,3,4,5,6)

4. Parameter collection (collect keyword parameters)

  • python supports parameters with two asterisks in addition to parameters with one model. Its function is to collect keyword parameters.
  • A function can take at most one star parameter (collection location parameter) and one two star parameter (collection keyword parameter).
  • The binary parameter exists in the form of a dictionary inside the function.
  • The two-star parameter must be at the end of the parameter list. There can be no other keyword parameters and location parameters after it.
# Test one satellite parameters and two satellite parameters
def test_star(a, b, c, *onestar, **twostar):
    print('a = %d; b = %d; c = %d' % (a, b, c))
    print(onestar, type(onestar))
    print(twostar, type(twostar))

test_star(1, 2, 3, 4, 5, 6, s1 = 7, s2 = 8, s3 = 9)
# In another order?
# test_star(1, 2, 3, 4, 5, 6, s1 = 7, s2 = 8, s3 = 9, a = 10, b = 11, c = 12)
# An error is reported. No keyword parameters can be passed after the two-star parameters (of course, neither can the location parameters)
  • The "parameter collection" function will collect as few parameters with stars as possible and leave more parameters to normal location parameters and keyword parameters
# If there are default parameters, pay attention to possible bug s
def test_star(a, b, c, p = 5, *onestar, **twostar):
    print('a = %d; b = %d; c = %d; p = %d' % (a, b, c, p))    #a = 1; b = 2; c = 3; p = 4
    print(onestar, type(onestar))            #(5, 6) <class 'tuple'>
    print(twostar, type(twostar))            #{'s1': 7, 's2': 8, 's3': 9} <class 'dict'>

# Will pass a p=4 in instead of the assumption, onestar=(4,5,6)
test_star(1, 2, 3, 4, 5, 6, s1 = 7, s2 = 8, s3 = 9)

5. Reverse parameter collection (explosion parameter)

  • Lists, tuples, dictionaries, etc. defined outside the parameters can be "exploded" when transmitting parameters, and the contents are automatically allocated to the parameter list
  • To "explode" a list or tuple, you need to add an asterisk in front of it.
  • "Bomb" dictionary needs to be preceded by two asterisks.
# Explosion parameter example
def zha(a,b,c):
    print(a,b,c)
# Fried tuple
z = (1,2,3)            #1 2 3
zha(*z)
# Fried list
z = [4,5,6]            #4 5 6
zha(*z)
# Fried dictionary
z = {'a':7,'b':8,'c':9}    #7 8 9
zha(**z)
# Fried dictionary
z = {'c':7,'a':8,'b':9}    #8 9 7
zha(**z)

# If the number of parameters or keys after explosion do not match, an error will be reported
# z = {'c':7,'a':8}
# zha(**z)

6. Memory management of parameters

  • python parameter passing, passing the parameter value rather than the parameter address. The parameter value is copied and passed to the progressive function.
  • For numeric parameters (integer, floating point, complex number, etc.), changing the parameter value inside the function is not affected outside the function.
  • For container type parameters (list, dictionary, string, etc.), the contents of the container are changed in the function, which can also be reflected outside the function.
# Pass numeric type parameters
# Modification within the function is not affected outside the function
def mod_para1(a,b):
    print('In mod_para1, before modification: a = %d; b = %d' % (a,b))    #a = 2; b = 8
    a *= 2
    b += 4
    print('In mod_para1, after modification: a = %d; b = %d' % (a,b))    #a = 4; b = 12
a = 2
b = 8
print('Out of mod_para1, before modification: a = %d; b = %d' % (a,b))    #a = 2; b = 8
mod_para1(a,b)
print('Out of mod_para1, after modification: a = %d; b = %d' % (a,b))    #a = 2; b = 8
  • Pass container type parameters
  • Modification inside the function can also be reflected outside the function, and this method can also be used to transfer information to the outside world
  • If you do not want the contents of the container type to be modified, use the copy.copy() copy.deepcopy() method manually
# When the list passes parameters through the function, the data is changed
def mod_para2(x):
    print('In mod_para2, before modification: x = ' + str(x))
    for i in range(len(x)):
        x[i] *= 2
    print('In mod_para2, after modification: x = ' + str(x))
x = [i for i in range(10)]
print('Out of mod_para2, before modification: x = ' + str(x))
mod_para2(x)
print('Out of mod_para2, after modification: x = ' + str(x))
import copy
A = [1,2,3]; B = copy.copy(A)
mod_para2(B); print(A,B)

7. Scope of variable in function

  • Created outside the function, it is Global and visible anywhere inside this py file.
  • It is created inside the function. It is Local. It can only be accessed inside the function and not visible outside the function.
  • Global variables and local variables have the same name. Local variables will be accessed inside the function and global variables will be accessed outside the function.
  • Function can access global variables, but cannot be modified!
  • If you have to modify a global variable inside a function, you need to declare it (this is not recommended!)
gv1 = 1
def test():
    # gv1=2
    print('To access global variables inside a function: gv1 = %d' % gv1)    #1
    # gv1=2
test()
print('To access global variables outside a function: gv1 = %d' % gv1)    #1
  • In the above example, an error will be reported in the previous line of gv1 = 2. It looks incredible.
  • In fact, this is Python's "hide" operation on global variables. When assigning a value to a non-existent variable inside a python function, the local variable will be redefined by default. In other words, gv1 is redefined inside the whole function. This operation will affect the whole function, so an error will be reported on its previous line.
  • In order to access the masked global variables, you need to use the globals() function to output the global variables in the form of a dictionary. (globals() ['global variable name'] -- or you can simply think that global variables are stored through the dictionary in globals()
  • At present, we know that there will be no error after Python 3.10, but this operation method is generally not recommended!
# Accessing masked global variables
gv1 = 1
def test():
    # Use the globals function to access the masked global variables
    print('To access global variables inside a function: gv1 = %d' % globals()['gv1'])
    gv1 = 2 
    print('Access the modified global variable inside the function: gv1 = %d' % gv1)
test()
print('To access global variables outside a function: gv1 = %d' % gv1) # The internal modification of the function is actually a local variable with the same name, and the global variable has not been modified.
  • Normal practice is that as long as a global variable is defined, the local variable inside the function should not have the same name as it!
  • Global statements can be used to declare global variables inside the function, and the declared global variables can be accessed and modified inside the function.
# Test global variables
gv1 = 1
def test():
    global gv1 #I'll control the global variables
    print('To access global variables inside a function: gv1 = %d' % gv1)    #1
    gv1+=1
test()
print('To access global variables outside a function: gv1 = %d' % gv1)    #2

8. Get variables within the specified range

  • python provides several methods that allow us to access the "name" of each variable and the "value" they hold
  • Variables store "name" and "value" pairs somewhere in memory
  • Globals(): returns the dictionary composed of all variables in the global scope, globals() ["name"]
  • locals(): returns a dictionary consisting of all variables in the current function range
  • vars(object): get the dictionary composed of all variables within the specified object range (if the object parameter is not passed in, the functions of vars and locals are exactly the same)
  • If locals() is called in the global scope (outside the function), it behaves like globals(), and lists all variables in the global scope
  • Generally speaking, the variable dictionaries listed in the above functions should not be modified! But in fact, they can be modified!! Modifying variables in this way is not recommended.

3, Local function (nesting of functions)

  • python can define functions inside functions, and multiple functions are nested with each other. Functions inside other functions are called "local functions".
  • Local functions are hidden from the outside and can only be used inside the function that defines them.
  • python functions can also be used as return values. If local functions are used as return values, they can be used in other functions.

One chestnut (switching of multiple average values using local functions)

# The switching of multiple average values is realized by using local functions
def mymean(x, mtype = 'arithmetic'):
    '''Calculation list x Average of, in mtype Defines which average value to calculate. The default value is arithmetic average( arithmetic mean)    '''
    def arithmetic(x): 
        ''' Arithmetic mean( arithmetic mean)  '''
        m = sum(x)/len(x);    return m
    def geometric(x): 
        '''Geometric mean( geometric mean) '''
        p = 1.;  n = len(x)
        for i in range(n):      p *= x[i]
        m = p ** (1/n);       return m
    def harmonic(x): 
        ''' Harmonic mean( harmonic mean) '''
        s = 0.;      n = len(x)
        for i in range(n):        s += 1/x[i]
        m = 1/(s/n);        return m
    if mtype == 'arithmetic':    return arithmetic
    elif mtype == 'geometric':    return geometric
    elif mtype == 'harmonic':     return harmonic
    else:        return arithmetic
  • Similar to the local variable masking the global variable in a function, the variable in a local function will also mask the local variable of its function.
  • Therefore, when using local functions, we should also pay attention to the problem of variable names. The variable names of functions at different levels should be different.
  • If you want to access the local variables of the previous function, you should declare them with nonlocal in the local function (similar to declaring global variables with global).
# If the variables in the local function conflict with the local variables in the function, this program will report an error
def test1():
    fv = 1
    def test2():
        # print('Print the local variables in the upper function within the local function:%d' % fv) # Will report an error here
        fv = 2
        print('Print the local variables in the upper function within the local function (after change):%d' % fv)    #2        
    test2()
    print('Print local variables in the upper function (after change):%d' % fv)    #1        
    return fv
print('Print local variables outside the upper function (after change):%d' % test1())    #1

Global variables can be used / changed using the nolocal declaration

# The variable in the local function conflicts with the local variable in the function. It should be changed so that no error is reported
def test1():
    fv = 1
    def test2():
        nonlocal fv # Use nonlocal declaration to declare fv as the variable of the upper function
        print('Print the local variables in the upper function within the local function:%d' % fv)    #1
        fv = 2
        print('Print the local variables in the upper function within the local function (after change):%d' % fv)    #2    
        
    test2()
    print('Print local variables in the upper function (after change):%d' % fv)    #2
    return fv

print('Print local variables outside the upper function (after change):%d' % test1())    #2

4, Advanced content of functions

  • Everything in python is an object, and a function is also an object. A function can be assigned to a variable, as a parameter of a function, or as a return value of a function.
  • The use of function as object in python can be compared with function pointer in c language, but it is much more flexible and less error prone than function pointer.
# Take the mymean function in chestnut in Chapter 3 as an example
# Assign function to variable f
f = mymean2('arithmetic')
# Print it out
print(f)
# Test it
x = list(range(1,10))
m = f(x)
print(m)
# You can also write it together like the example above
print(mymean2('geometric')(x))

1. Function as formal parameter of function

  • Sometimes it is necessary to define a function to fix the general internal process, but some parts can be replaced: similar to changing the engine for a car and changing the graphics card for a computer.
  • This "replaceable" programming method can be easily realized in python by taking functions as formal parameters.

2. Use function as return value

  • Taking a function object (which can be a local function or a function defined elsewhere) as the return value is suitable for judging which part to use in "part replacement" programming.
  • See the code in the local variable chestnut in Chapter 3 for the specific implementation
# Take the mymean function in chestnut in Chapter 3 as an example
# Write another program to transform the numbers in the list into another list with an average of 1
# Mean value can be arithmetic mean value, geometric mean value and harmonic mean value
def mynormalize(x, mtype):
    f = mymean(mtype)
    m = f(x)
    return [i/m for i in x]

x = list(range(1,10))
mtype = 'geometric'
print(mymean(mtype)(x))
print(mynormalize(x, mtype))

3. Recursion

  • Calling itself in a function is called recursion.
  • Recursion can be regarded as an implicit loop, which can execute a piece of code repeatedly without loop statement control.
  • Recursion is very useful in large and complex programs, and can be used in both numerical and non numerical algorithms!
  • When using recursion, it should be noted that when a function calls itself continuously, it must ensure that the return value of the function is determined at a certain time, that is, it will not call itself again.
# Fibonacci sequence
# Fibonacci sequence has direct applications in modern physics, quasicrystal structure, chemistry and other fields
def Fibonacci(n):
    '''    Fibonacci sequence
    f(0)=1, f(1) = 1, f(n) = f(n-1)+f(n-2)    '''
    if n == 0 or n == 1:        return 1
    else:      return Fibonacci(n-1) + Fibonacci(n-2)
# Test it. Note that n should not be set too large. The recursive efficiency of python is relatively low and it will crash too often
print(Fibonacci(5))
# Fibonacci series, top 20
print('Fibonacci sequence:')
for i in range(20):
    print('%d: %d' % (i,Fibonacci(i)))

5, Local functions and lambda  

  • lambda expression is a function implementation method introduced by modern programming language. It can replace local functions to a certain extent.
  • For a local function, its name is only meaningful inside the function, and its name cannot be seen outside the function. Even if it is passed in the form of return value, its name is not passed at the same time.
  • In the sense of naming, local functions are "anonymous". No one knows the name of this function.
  • lambda expressions are equivalent to anonymous functions.
# hello world in one line
greeting = lambda: print('Hello lambda!')
greeting()
# lambda expressions can be placed in arrays and run in batches
L = [lambda x: x**2, lambda x: x**3, lambda x: x**4]
for p in L:
    print(p(3))

1. Replace local functions with lambda expressions

# Replacing local functions with lambda expressions
def mymean2(mtype = 'arithmetic'):
    '''    Returns the function used to calculate the average, using mtype Defines which average value to calculate. The default value is arithmetic average( arithmetic mean)    '''
    # Since the lambda expression can only write one line, it is implemented with the ready-made functions of numpy and scipy
    import numpy as np
    import scipy.stats as st
    a = np.array(x)
    if mtype == 'arithmetic': # arithmetic mean
        return lambda a: np.mean(a)
    elif mtype == 'geometric':# geometric mean
        return lambda a: st.gmean(a)
    elif mtype == 'harmonic': # harmonic mean
        return lambda a: st.hmean(a)
    else:        # Default: arithmetic mean
        return lambda a: np.mean(a)

x = list(range(1,10))
print(x)
print(mymean2('arithmetic')(x))
print(mymean2('geometric')(x))
print(mymean2('harmonic')(x))

2. Internal functions of common mathematical methods

# Judge whether all elements are True, which is equivalent to multiple and
help(all)
print(all([3>2,6<9]))
# Whether any element is True is equivalent to multiple or
help(any)
print(any([3>2,6<9]))
# Maximum and minimum
help(max)
help(min)
print(max([1,2,5,3]))
print(min([1,2,5,3]))
# Rounding (to the nth place after the decimal point)
help(round)
print(round(3.1415926,3))

# Add all elements 
help(sum)
print(sum([1,2,3]))
print(sum([1,2,3],5))
# Power
help(pow)
print(pow(6,2))
print(pow(6,2,5))
# Division with remainder
help(divmod)
print(divmod(6,2))
# absolute value
help(abs)
print(abs(-2.56))

This is the end of the detailed explanation of this issue. I hope it will be helpful to you. Thank you for watching!

I will continue to update the relevant knowledge of programming and learning. Welcome to pay attention to my blog. Your praise and attention are the driving force for me to continue to share.

Welcome to the column [the strongest in the whole network] Python system learning manual , if you have any questions, you can comment or communicate by private letter. Thank you!

Posted by KingWylim on Mon, 25 Oct 2021 07:24:53 -0700