4. Function
1 #!/user/bin/env python 2 # -*- coding:utf-8 -*- 3 """ 4 Function ; 5 Is Mutable 6 mutable : 7 list set dict 8 immutable : If you modify the value of a variable, address changes too 9 int str float tuple 10 11 Copy : Back up a container's data in a new address 12 shallow copy: 13 1. For the immutable type Number String Tuple, shallow replication is just address pointing, 14 and does not open up new space. 15 2. For variable types List, Dictionary, Set, shallow replication opens up new spatial addresses 16 (just the top level opens up new space, and the element addresses in the inner layer are the same), 17 and shallow replication takes place. 18 3. After shallow copy, changing the value of elements of variable type in the original object will affect 19 the copy object at the same time; changing the value of elements of variable type in the original object, 20 only the original type is affected. 21 22 numbers = [1, 2, 3, [4, 5, 6]] 23 new_numbers = numbers.copy() 24 numbers[3][0] = 7 25 numbers 26 # >>> [1, 2, 3, [7, 5, 6]] 27 new_numbers 28 # >>> [1, 2, 3, [7, 5, 6]] 29 deep copy: 30 1. In addition to the top-level copy, 31 the deep copy also copies the sub-elements (essentially recursive shallow copy) 32 2. After deep copy, all element addresses of the original object and the copy object are not the same. 33 34 import copy 35 numbers = [1, 2, 3, [4, 5, 6]] 36 numbers[3][0] = 7 37 numbers 38 # >>> [1, 2, 3, [7, 5, 6]] 39 new_numbers 40 # >>> [1, 2, 3, [4, 5, 6]] 41 42 Ordinary Function : 43 Format 44 def function_name([param....]): 45 Function Body 46 47 Invoking: 48 function_name([param....]) 49 50 Invoking between functions 51 52 Param and Return value : 53 Param 54 General Parameters 55 list, set, dict 56 str, tuple, int, float 57 58 Default value Parameters 59 def func(a, b=[Fixed Value]): 60 # :param a: 61 # :param b: # default b = [Fixed Value] 62 # :return: 63 pass 64 65 func(5) 66 # >>> a = 5, b = [Fixed Value] 67 func(5, 10) 68 # >>> a = 5, b = 10 69 Keyword Parameters 70 Specify invoking parameters 71 72 Variable Parameters 73 Unpacking 74 def func(*args, **kwargs): 75 print(args) 76 print(kwargs) 77 78 numbers = [1, 2, 3, 4, 5] 79 dictionary = {"YeYuanXinZhiZhu": 5, "TieBiATongMu": 7} 80 81 func(numbers, 10, dictionary) 82 # >>> ([1, 2, 3, 4, 5], 10, {"YeYuanXinZhiZhu": 5, "TieBiATongMu": 7}) 83 # >>> {} 84 func(*numbers, 10, dictionary) 85 # >>> (1, 2, 3, 4, 5, 10, {'YeYuanXinZhiZhu': 5, 'TieBiATongMu': 7}) 86 # >>> {} 87 func(*numbers, 10, **dictionary) 88 # >>> (1, 2, 3, 4, 5, 10) 89 # >>> {"YeYuanXinZhiZhu": 5, "TieBiATongMu": 7} 90 91 packing 92 numbers = [1, 2, 3, 4, 5] 93 x, *y, z = numbers 94 # >>> x y z 95 # >>> 1 [2, 3, 4] 5 96 def add(*args) 97 pass 98 99 Return Value 100 1. Return the result to the invoking place and return the control of the program together 101 2. If the function does not return, default return a None object 102 3 .If multiple objects are returned, 103 the interpreter encapsulates multiple objects into a tuple and returns them as a whole. 104 105 def func(): 106 return 107 # >>> func() 108 # >>> None 109 110 def func(): 111 return value 112 # >>> func() 113 # >>> value 114 115 def func(): 116 return value_1, value_2, value_3, 117 # >>> func() 118 # >>> (value_1, value_2, value_3) 119 120 Scope 121 Local 122 Functions can only change their own variables 123 locals() Return the dictionary containing the current scope's local variables. 124 Usually used in functions, 125 Enclosing 126 1. An interior function is defined in an exterior function. 127 2. Temporary variables of the exterior function are used in the interior function 128 3. the return value of the exterior function is the reference of the interior function. 129 Global 130 globals() Return the dictionary containing the current scope's global variables. 131 Variables generated by default and User-defined variable 132 Builtins 133 134 Functions are used as parameters 135 136 Decorator : They are functions that modify the function of a function 137 decorator param : Implementation of Three-Level functions 138 def first_decorator(Param): 139 def second_decorator(Func): 140 def third_decorator(*args, **kwargs): 141 pass 142 return third_decorator 143 return second_decorator 144 145 multilayer decorator 146 def first_decorator(func): 147 def wrapper(*args, **kwargs): 148 pass 149 return wrapper 150 151 def second_decorator(func): 152 def wrapper(*args, **kwargs): 153 pass 154 return wrapper 155 156 @second_decorator # param = function first_decorator.<locals>.wrapper at ... 157 @first_decorator # Executing closer first 158 def foo(): # foo = function second_decorator.<locals>.wrapper at ... 159 pass 160 161 Anonymous Functions and High-Order Functions: 162 Anonymous Functions Format : lambda param : return value 163 func = lambda x: x + 1 164 func(5) 165 # >>> 6 166 167 Using Anonymous Function combine with High-Order Function 168 1. A function can be passed as a parameter to another function 169 2. The return value of a function is another function 170 171 sorted : sorted(iterable, key, reverse) -> list 172 numbers = [5, 2, 6, 12, 10, 37] 173 print(sorted(numbers)) 174 # >>> [2, 5, 6, 10, 12, 37] 175 176 # Sort by age 177 numbers = [("GeBiCunGaHa", 25), ("YeYuanXinZhiZhu", 5), ("TieBiATongMu", 7)] 178 print(sorted(numbers, key=lambda x: x[1])) 179 # >>> [("YeYuanXinZhiZhu", 5), ("TieBiATongMu", 7), ("GeBiCunGaHa", 25)] 180 print(sorted(numbers, key=lambda x: x[1])) 181 # >>> [("GeBiCunGaHa", 25), ("TieBiATongMu", 7), ("YeYuanXinZhiZhu", 5)] 182 183 map : map(function, *iterables) -> map object 184 print(list(map(lambda x: x ** 2, [1, 2, 3, 4, 5]))) 185 # >>> [1, 4, 9, 16, 25] 186 187 print(list(map(lambda x, y: x + y, [1, 2, 3], [4, 5, 6])) 188 # >>> [5, 7, 9] 189 190 filter : filter(function or None, iterable) -> filter object 191 numbers = [0, 1, 2, 3, 4, 5] 192 print(list(filter(lambda x: x % 2 == 0, numbers))) 193 # >>> [1, 2, 3, 4, 5] 194 195 numbers = [1, 2, 3, 4, 5] 196 print(list(filter(None, numbers))) 197 # >>> [0, 2, 4] 198 199 reduce : reduce(function, sequence[, initial=None]) -> value 200 from functools import reduce 201 numbers = [1, 2, 3, 4, 5] 202 print(reduce(lambda x, y: x + y), numbers) 203 # >>> 15 204 205 numbers = [1, 2, 3, 4, 5] 206 print(reduce(lambda x, y: x + y), numbers, 10) 207 # >>> 25 208 209 Extended content 210 partial 211 from functools import partial 212 def add(x, y): 213 return x + y 214 215 new_add = partial(add, 5) 216 print(new_add(4)) 217 # >>> 9 218 wraps 219 from functools import wraps 220 221 Comprehensions : 222 List Comprehensions 223 numbers = [1, 3, 5, 7, 9, 2, 4, 6, 8] 224 new_numbers = [x for x in numbers if x % 2 == 0] 225 # >>> [2, 4, 6, 8] 226 new_numbers = [x if x % 2 == 0 else x + 1 for x in iterables] 227 # >>> [2, 4, 6, 8, 10, 2, 4, 6, 8] 228 [(x, y) for x in iterables1 for y in iterables2] 229 Set Comprehensions 230 numbers = [1, 2, 3, 4, 1, 2, 3, 4] 231 new_numbers = {x for x in numbers if x % 2 == 0} 232 # >>> {2, 4} 233 new_numbers = {x if x % 2 == 0 else x + 1 for x in iterables} 234 # >>> {2, 4} 235 dict Comprehensions 236 dictionary = {"a": 1, "b": 2, "c": 3} 237 new_dictionary = {value: key for key, value in dictionary.items()} 238 # >>> {1: 'a', 2: 'b', 3: 'c'} 239 Generator : 240 The mechanism of one-sided loop and one-sided computation 241 Define : 242 List Comprehension's symbols are replaced by () 243 combining with the method named "next()" for getting the next element 244 generator = (x for x in range(10) if x % 2 == 0) 245 next(generator) 246 # >>> 0 247 next(generator) 248 # >>> 2 249 yield method and function 250 yield : 1. return 2.stop 251 combining with the method named "next()" for getting the next element 252 if function has return values, the return value will throw as a error named "StopIteration" + value 253 def func(): 254 for i in range(5): 255 yield i 256 print("This is {} step".format(i) 257 258 generator = func() 259 print(generator) 260 # >>> <object generator func at ......> 261 print(next(generator)) 262 # >>> 0 263 # >>> this is 0 step 264 print(next(generator)) 265 # >>> 1 266 # >>> this is 1 step 267 Method : 268 generator.close() 269 generator.__next__() is equal to next(generator) 270 generator.send() 271 the first parameter must be None 272 273 Application : Multitask switching 274 def study(): 275 pass 276 277 def listen_music(): 278 pass 279 280 def chat(): 281 pass 282 283 The relationship between iterable objects, iterators and generators : 284 285 ↓next() or object.__next__() 286 ↑---→ iterators--→ generators 287 iterable Objects ↑iter() 288 ↓ ↑ ↑---→ Sequence(list, tuple, string) 289 \→ Non-iterator 290 \---→ dictionary 291 292 Example : 293 from collections import Iterator, Iterable 294 isinstance(range(0, 5), Iterator) 295 # >>> False 296 isinstance(range(0, 5), Iterable) 297 # >>> True 298 299 Recursion Function : 300 Recursion functions must have exits and keep approaching them 301 302 Example : Implementing Fibonacci Sequence by Recursion 303 def fibonacci(n): 304 if n == 1 or n == 2: 305 return 1 306 return fibonacci(n - 1) + fibonacci(n - 2) 307 """