Fourth Chapter function
4.1 Calling Functions
1, Python built-in a lot of useful functions, you can directly call
such as: ABS (), Max ()
2. Data type conversion
>>>int (' 123 ')
123
>>>str (123)
' 123 '
>>>bool (1)
True
3, the function name is actually refers to a function object reference, can completely assign the function name to a variable, equivalent to give this function an "alias":
>>> a = ABS # variable a points to ABS function
>>> A (-1) # So you can also call ABS function via a
1
4, built-in hex () function can convert an integer to a hexadecimal representation of the string
"Summary"
Calling the Python function requires passing in the correct argument based on the function definition. If the function call is wrong, be sure to learn to read the error message, So English is very important.
4.2 Defining functions
1, define a function to use the DEF statement, in turn, write the function name, parentheses, parameters in parentheses and colons:, and then, in the indentation block to write the function body, the return value of the function return statement.
def my_abs (x):
If x >= 0:
return x
Else
Return–x
If there is no return statement, the function completes after execution and returns the result, except that the result is none.
Return none can be abbreviated to return.
2. Null function
If you want to define an empty function that doesn't do anything, you can use the PASS statement
Def NOP ():
Pass
The pass statement doesn't do anything. In fact, pass can be used as a placeholder, such as the code that has not yet figured out how to write the function, you can put a pass first so that the code can run.
Pass can also be used in other statements, such as:
If age >= 18:
Pass
Without pass, the code will run with a syntax error.
3. Parameter Check
when calling a function, if the number of arguments is not correct, the Python interpreter automatically checks it out and throws TypeError:
data type checking can be implemented with built-in functions isinstance ():
After you have added a parameter check, the function can throw an error if you pass in the wrong parameter type:
def my_abs (x):
If not isinstance (x, (int, float)):
Raise TypeError (' bad operand type ')
If x >= 0:
return x
Else
Return-x
>>> my_abs (' A ')
Traceback (most recent Calllast):
File "<stdin>", line 1, in<module>
File "<stdin>", line 3, Inmy_abs
Typeerror:bad operand type
4. Return Multiple values
Import Math
def move (x, Y, step,angle=0):
NX = x + step * Math.Cos (angle)
NY = y-step * Math.sin (angle)
Return NX, NY
But it's just an illusion, and the Python function returns a single value:
>>> r = Move (100,100, MATH.PI/6)
>>> Print (R)
(151.96152422706632, 70.0)
The original return value is a tuple. However, in syntax, returning a tuple can omit parentheses, and multiple variables can receive a tuple at the same time, by position to the corresponding value, so Python's function to return a multi-valued is actually to return a tuple, but it is more convenient to write.
"Summary"
(1) When defining functions, we need to determine the number of function names and parameters;
(2) If necessary, the data types of the parameters can be checked first;
(3) The function body can return the function result at any time.
(4) When the function is finished and there is no return statement, Automatic Returnnone is performed.
(5) A function can return multiple values at the same time, but it is actually a tuple.
if it is an imaginary figure, you need to refer to the Python built-in Cmath function library, such as:
cmath.sqrt ( -1)
4.3 parameters of the function
Python's function definition is very simple, but the flexibility is very large. In addition to the required parameters that are normally defined, you can use default parameters, variable parameters, and keyword parameters so that the interface defined by the function can handle complex parameters as well as simplify the caller's code.
1. Position parameter
For example: Power (x, N), used to compute xn
The Power (x, N) function has two parameters: X and N, both of which are positional parameters, and when the function is invoked, the incoming two values are assigned to parameters x and N in order of position.
2. Default Parameters
Power (x, n=2):
Call Power (5), equivalent to power (5,2)
Attention
When setting default parameters, there are a few things to note:
The first is the required parameter, the default parameter is later, otherwise the Python interpreter will give an error (consider why the default parameter cannot be placed in front of the required parameters);
The second is how to set the default parameters.
When a function has more than one parameter, the parameter that is changed is placed in front, and the small variable is put behind. Parameters that vary little can be used as default parameters.
What is the benefit of using default parameters. The biggest advantage is that it can reduce the difficulty of calling a function.
def enroll (name, Gender, age=6, city= ' Beijing ')
only students who are not in conformity with the default parameters need to provide additional information:
Enroll (' Bob ', ' M ', 7)
Enroll (' Adam ', ' M ', city= ' Tianjin ')
The default parameters are useful, but improper use can also fall into the pit. The default parameter has one of the largest pits, as demonstrated below:
First define a function, pass in a list, add an end and return:
def add_end (l=[]):
L.append (' End ')
Return L
When you call normally, the result seems to be good:
>>> Add_end ([1, 2, 3])
[1, 2, 3, ' end ']
>>> add_end ([' X ', ' y ', ' z '])
[' x ', ' y ', ' z ', ' End ']
When you use the default parameter invocation, the first result is also true:
>>> Add_end ()
[' End ']
However, when you invoke Add_end () again, the result is incorrect:
>>> Add_end ()
[' End ', ' end ']
>>> Add_end ()
["End", "End", "End"]
Many beginners are puzzled that the default parameter is [], but the function seems to "remember" the list that was last added ' end ' every time.
Explanations for the reasons are as follows:
When the Python function is defined, the value of the default parameter L is computed. That is [], because the default parameter L is also a variable, it points to the object [], each time the function is called, if the contents of L are changed, the contents of the default parameter will be changed at the next call, no longer the [] of the function definition.
so, to define the default parameters, keep in mind that the default argument must point to the invariant object.
To modify the example above, we can implement the invariant object with none:
def add_end (L=none):
If L is None:
L = []
L.append (' End ')
Return L
Now, no matter how many times you call, there is no problem:
>>> Add_end ()
[' End ']
>>> Add_end ()
[' End ']
Why do you want to design a constant object such as Str and none? Because once the invariant object is created, the data inside the object cannot be modified, thus reducing the error caused by the modification of the data. In addition, because the object is invariant, the multitasking environment reads the object without the need for locking, while reading the problem is not. When we write a program, if we can design a invariant object, then try to design unchanged objects.
3. Variable Parameters
We take the mathematics titled example, given a set of numbers a,b,c ..., please compute A2 + b2 + C2 + ...
Because the number of parameters is not certain, we first think that we can put a,b,c ... As a list or tuple, so that the function can be defined as follows:
def calc (numbers):
sum = 0
For N in numbers:
sum = SUM + N * n
return sum
But when you call, you need to assemble a list or tuple first:
>>> Calc ([1, 2, 3])
14
>>> Calc ((1, 3, 5, 7))
84
If you take advantage of variable parameters, the way you call a function can be simplified as follows:
>>> Calc (1, 2, 3)
14
>>> Calc (1, 3, 5, 7)
84
So, we change the parameter of the function to the variable parameter:
Def calc (*numbers):
sum = 0
For N in numbers:
sum = SUM + N * n
return sum
>>>calc (1,2,3,4,5)
When defining a variable parameter and defining a list or tuple parameter, only a * number is added to the parameter. Inside the function, the parameter numbers receives a tuple, so the function code is completely unchanged. However, when you call the function, you can pass in any of the arguments, including 0 parameters:
>>> Calc (1, 2)
5
>>> Calc ()
0
If you already have a list or tuple, what to do if you want to invoke a variable parameter. You can do this:
>>> nums = [1, 2, 3]
>>> Calc (nums[0], nums[1], nums[2])
14
This kind of writing is certainly feasible, the problem is too cumbersome, so python allows you to add a * number in front of the list or tuple, the list or tuple elements into variable parameters to pass in:
>>> nums = [1, 2, 3]
>>> Calc (*nums)
14
*nums says that all the elements of the Nums list are passed in as variable parameters. This kind of writing is quite useful and very common.
4, keyword parameters
Variable parameters allow you to pass in 0 or any of the parameters, which are automatically assembled as a tuple when the function is called. The keyword parameter allows you to pass in 0 or any parameter with a parameter name, which is automatically assembled into a dict within the function. Take a look at the example:
def person (name, age, **kw):
Print (' name: ', Name, ' Age: ', age, ' other: ', kw)
The function person accepts the keyword parameter kw in addition to the required parameter name and age. When you call the function, you can pass in only the required parameters:
>>>person (' Michael ', 30)
Name:michael age:30 other:{}
You can also pass in any number of keyword parameters:
>>> person (' Bob ', city= ' Beijing ')
Name:bob age:35 other:{' city ': ' Beijing '}
>>> person (' Adam ', gender= ' M ', job= ' Engineer ')
Name:adam age:45 other:{' gender ': ' M ', ' job ': ' Engineer '}
the function of a keyword parameter: it can extend the function of a function.
Similar to variable parameters, you can also assemble a dict, and then convert the dict to a keyword parameter:
>>> extra = {' City ': ' Beijing ', ' job ': ' Engineer '}
>>> person (' Jack ", city=extra[' city '], job=extra[' job ')
Name:jack age:24 other:{' city ': ' Beijing ', ' job ': ' Engineer '}
Of course, the complex calls above can be written in simplified notation:
>>> extra = {' City ': ' Beijing ', ' job ': ' Engineer '}
>>> person (' Jack ', **extra)
Name:jack age:24 other:{' city ': ' Beijing ', ' job ': ' Engineer '}
**extra said that extra this dict all key-value with keyword parameters passed to the function of the **kw parameter, KW will get a dict, note kw dict is a copy of the extra, the changes to KW will not affect the extra outside the function.
5, named keyword parameters
For keyword parameters, the caller of a function can pass in any unrestricted keyword parameter. As for what is passed in, it needs to be checked by kw inside the function.
Still take the person () function as an example, we want to check for City and job parameters:
def person (name, age, **kw):
If ' City ' in kw:
# There are city parameters
Pass
If ' job ' in kw:
# There are job parameters
Pass
Print (' name: ', Name, ' Age: ', age, ' other: ', kw)
However, the caller can still pass in the Unrestricted keyword parameter:
>>> person (' Jack ', city= ' Beijing ', addr= ' Chaoyang ', zipcode=123456)
if you want to restrict the name of a keyword parameter, you can use a named keyword parameter, for example, to receive only city and job as key parameters. The functions defined in this way are as follows:
def person (name, age, *, City, job):
Print (name, age, City,job)
Unlike keyword parameter **kw, a named keyword parameter requires a special delimiter *,* subsequent arguments are treated as named keyword parameters.
The method is invoked as follows:
>>> person (' Jack ', city= ' Beijing ', job= ' Engineer ')
Jack Beijing Engineer
If a variable parameter is already in the function definition, a special delimiter is no longer required for the named keyword argument followed:
def person (name, age, *args, City, Job):
Print (name, age, args,city, job)
The named keyword parameter must pass in the parameter name, which is different from the positional parameter. If the parameter name is not passed in, the call will error:
A named keyword parameter can have a default value, which simplifies the invocation:
def person (name, age, *, city= ' Beijing ', job):
Print (name, age, City,job)
Because the named keyword parameter city has a default value, it is not passed in the city parameter when invoked:
>>> person (' Jack ', job= ' Engineer ')
Jack Beijing Engineer
when using named keyword parameters, it is important to note that if there are no mutable parameters, you must add a * as a special separator. If the *,python interpreter is missing, positional parameters and named keyword parameters will not be recognized:
def person (name, age, City, job):
# missing *,city and job are considered positional parameters
Pass
6. Parameter Combination
You define functions in Python by using required parameters, default parameters, variable parameters, keyword parameters, and named keyword parameters, all of which can be combined in a combination of 5 parameters. Note, however, that the order of the parameter definitions must be: required, default, variable, named keyword, and keyword parameters.
For example, define a function that contains several of these parameters:
Def f1 (A, B, c=0, *args, **kw):
Print (' A = ', A, ' B = ', B, ' C = ', C, ' args = ', args, ' kw = ', kw)
def F2 (A, B, c=0, *, D, **kw):
Print (' A = ', A, ' B = ', B, ' C = ', C, ' d = ', D, ' kw = ', kw)
When the function is called, the Python interpreter automatically passes the corresponding arguments in the parameter position and the argument name.
>>> F1 (1, 2)
A = 1 b = 2 c = 0 args = () kw = {}
>>> F1 (1, 2, c=3)
A = 1 b = 2 c = 3 args = () kw = {}
>>> F1 (1, 2, 3, ' A ', ' B ')
A = 1 b = 2 c = 3 args = (' A ', ' b ') kw = {}
>>> F1 (1, 2, 3, ' A ', ' B ', x=99)
A = 1 b = 2 c = 3 args = (' A ', ' b ') kw = {' X ': 99}
>>> F2 (1, 2, d=99, Ext=none)
A = 1 b = 2 c = 0 d = kw = {' ext ': None}
The most amazing thing is that you can call the above function through a tuple and dict:
>>> args = (1, 2, 3, 4)
>>> kw = {' d ': $, ' x ': ' # '}
>>> F1 (*args, **kw)
A = 1 b = 2 c = 3 args = (4,) kw = {' d ': $, ' x ': ' # '}
>>> args = (1, 2, 3)
>>> kw = {' d ': +, ' x ': ' # '}
>>> F2 (*args, **kw)
A = 1 b = 2 c = 3 D = kw = {' X ': ' # '}
therefore, for any function, it can be invoked in the form of a similar func (*args, **kw), regardless of how its parameters are defined.
"Summary"
(1) Python's function has a very flexible parameter shape, which can be used to achieve simple invocation and can pass in very complex parameters.
(2) The default parameter must use the Mutable object, if it is a mutable object, the program will run with logic errors.
(3) Note the syntax for defining variable parameters and keyword parameters:
(4) *args is a variable parameter, args receives a tuple;
(5) **kw is a keyword parameter, kw receives a dict.
(6) and how to pass the syntax of a variable parameter and keyword parameter when calling a function:
(7) Variable parameters can be directly passed in: Func (1, 2, 3), you can first assemble the list or tuple, and then through the *args into: Func (* (1, 2, 3));
(8) keyword parameters can be directly passed in: Func (A=1, b=2), can be assembled dict first, and then through the **kw into: func (**{' a ': 1, ' B ': 2}).
(9) The use of *args and **kw is Python's customary way of writing, of course, you can use other parameter names, but it is best to use idiomatic usage.
(10) The named keyword parameter is intended to limit the number of parameter names that the caller can pass in, while providing default values.
(11) Define a named keyword parameter do not forget to write the delimiter without a variable parameter, otherwise the positional parameter will be defined.
4.4 Recursive Functions
1. The use of recursive functions should be careful to prevent stack overflow. In the computer, the function call is through stack (stack) This kind of data structure realizes, whenever enters a function call, the stack will add the stack frame, each time function returns, the stack will reduce one layer stack frame. Because the size of the stack is not infinite, the number of recursive calls can be excessive, resulting in stack overflow.
2, to solve the recursive call stack overflow method is through the tail recursive optimization, in fact, tail recursion and the effect of the loop is the same, so the cycle as a special tail recursive function is also possible.
Tail recursion refers to the call itself when the function returns, and the return statement cannot contain an expression. In this way, the compiler or interpreter can optimize the tail recursion, so that the recursive itself, no matter how many times, only occupy a stack frame, there will be no stack overflow.
The fact (n) function above has introduced a multiplication expression in return n * fact (n-1), so it is not a tail-recursion. To change to the tail recursive way, need a little more code, mainly to the product of each step into the recursive function:
def fact (N):
Return Fact_iter (n, 1)
def fact_iter (num, product):
If num = 1:
Return product
Return Fact_iter (num-1, num * product)
As you can see, return fact_iter (num-1, num * product) returns only the recursive function itself, and num-1 and num * Product are evaluated before the function call and do not affect the function call.
Fact (5) the corresponding Fact_iter (5, 1) calls are as follows:
===> Fact_iter (5, 1)
===> Fact_iter (4, 5)
===> Fact_iter (3, 20)
===> Fact_iter (2, 60)
===> Fact_iter (1, 120)
===> 120
When a tail recursive call is made, if optimized, the stack does not grow, so no matter how many calls it will not cause a stack overflow.
Unfortunately, most programming languages do not optimize for tail recursion, and the Python interpreter does not do optimizations, so even changing the above fact (n) function to tail recursion can result in a stack overflow.
"Summary":
(1) The advantage of using recursive functions is that logic is simple and clear, the disadvantage is that excessive calls can cause stack overflow.
(2) the language which is optimized for tail recursion can prevent stack overflow by tail recursion. tail recursion is actually equivalent to a loop, and a programming language without a looping statement can only implement loops through tail recursion.
(3) The Python standard interpreter does not optimize for tail recursion, and any recursive function has a stack overflow problem.
Write yourself a fact (n) function that doesn't have to be recursive
def FAC (n):
result = 1
For I in Range (1,n+1,1):
Result *= I
return result
Simple.
Change to use a while loop form:
def FAC (n):
result = 1
i = 1
While I <= n
Result *= I
i+= 1
return result