Function
def my_func(param1, param2, ..., paramN):
statements
return/yield value # optional
The function must be defined before using it.
-
We don't have to define the type of params.
-
We can write function inside a function (Nested function)
This feature brings some advantages:
- keep the inside function private
- improve the efficiency
More importantly, we can create
closure
. It's a function returns the inner function.Inner function uses the environment provided by outer function.
def nth_power(exponent): def exponent_of(base): return base ** exponent return exponent_of square = nth_power(2) cube = nth_power(3) print(square(3)) # 9 square uses the env which has exponent == 2 print(cube(5)) # 125
Default params
Default param always point to an immutable object
def add_end(L=[]):
L.append('END')
return L
add_end() # ['END']
add_end() # ['END', 'END']
We can change the function.
def add_end(L=None):
if L is None:
L = []
L.append('END')
return L
Changable params
We can use *params
to represent multiple params of a function. Python passes these params into a tuple
automatically.
def calc(*numbers):
sum = 0
for n in numbers:
sum = sum + n * n
return sum
calc(1, 2, 3) # 14
nums = [1, 2, 3]
calc(*nums) # 14
keyword params
We can use **kw
to represent k-v
params. Python passes them into dict
.
def person(name, age, **kw):
print('name:', name, 'age:', age, 'other:', kw)
person('Bob', 35, city='Beijing') # Bob age: 35 other: {'city': 'Beijing'}
extra = {'city': 'Beijing', 'job': 'Engineer'}
person('Jack', 24, **extra) # name: Jack age: 24 other: {'city': 'Beijing', 'job': 'Engineer'}
If we want to set limits on key
, we can defind function:
# function only takes city and job as the key of **kw
# * separate normal params from keyword params
def person(name, age, *, city, job):
print(name, age, city, job)
# If function has changable params, we don't need *.
def person(name, age, *args, city, job):
print(name, age, args, city, job)
To put normal params
, default params
, changable params
, keyword params
all together.
def f1(a, b, c=0, *args, **kw):
print('a =', a, 'b =', b, 'c =', c, 'args =', args, 'kw =', kw)
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}
Function variable scope
-
Variable created in the function only works in function
-
Function can use Global Variable, but it can't change it. If we want to change it, we must use keyword
global
.MIN_VALUE = 1 def validation_check(value): global MIN_VALUE ... MIN_VALUE += 1
-
If the local variable and global variable has the same name, function will use local variable.
-
If Nested function want to use the variable of outer function, it needs to use keyword
nonlocal
.def outer(): x = "local" def inner(): nonlocal x x = 'nonlocal' print("inner:", x) inner() print("outer:", x) outer() # inner: nonlocal # outer: nonlocal
lambda function
lambda argument1, argument2,... argumentN : expression
lambda function focus at tasks which are:
-
simple
-
use only once (or few times)
l = [(1, 20), (3, 0), (9, 10), (2, -1)]
l.sort(key=lambda x: x[1]) # sorted by the second element of each tuple
print(l)
# [(2, -1), (3, 0), (9, 10), (1, 20)]
There are some built-in function work with lambda function:
-
map(function, iterable)
:l = [1, 2, 3, 4, 5] new_list = map(lambda x: x * 2, l) # [2, 4, 6, 8, 10]
-
filter(function, iterable)
:l = [1, 2, 3, 4, 5] new_list = filter(lambda x: x % 2 == 0, l) # [2, 4]
-
reduce(function, iterable)
:l = [1, 2, 3, 4, 5] product = reduce(lambda x, y: x * y, l) # 1*2*3*4*5 = 120