集合
主要作用:
1去重
2.关系测试
a = {1, 3, 5, 7, 8, 9}b = {2, 5, 6, 7, 8, 9}交集print(a & b) 或 print(a.intersection(b)){ 8, 9, 5, 7}差集print(a - b) 或 print(a.difference(b)){ 1, 3}并集print(a | b) 或 print(a.union(b)){ 1, 2, 3, 5, 6, 7, 8, 9}反向对称差集(并集-交集)print(a ^ b){ 1, 2, 3, 6}直接用a与b的差集更新aa.difference_update(b)print(a){ 1, 3}print(b){ 2, 5, 6, 7, 8, 9}
函数
1.减少重复代码
2.易扩展、易维护
函数有两种参数
1.形参:只有在被调用时才分配内存,调用结束后立刻释放内存,值仅在函数内部有效(局部变量,形参的作用域只在当前函数内部)
2.实参:有确定的值参数,所有的数据类型都可以被当做参数传给参数。
局部变量和全局变量
局部变量:作用域只在当前函数内部,外部变量默认不能被函数内部修改,只能引用。
全局变量:如果在函数内部修改函数外部的全局变量,必须使用global。
def change(n): print(n) # 引用的全局变量 n = "局部变量" # 局部变量 print(n)n = '全局变量'change(n)print(n)全局变量局部变量全局变量 def change(n): print(n) # 引用的全局变量 global k k = "局部变量" # 局部变量 print(k)k = '全局变量'change(k)print(k)全局变量局部变量全局变量
函数内部可以修改列表,字典,集合和实例
def change(n): print(n) # 引用的全局变量 n.append('Anna') # 局部变量 print(n)n = ['Jack', 'Mike']change(n)print(n)['Jack', 'Mike']['Jack', 'Mike', 'Anna']['Jack', 'Mike', 'Anna']
def change(n): print(n) # 引用的全局变量 n['Anna'] = 40 # 局部变量 del n['Mike'] # 局部变量 n['Jack'] = 50 print(n) n = {'Jack': 20, 'Mike': 30 } change(n) print(n)
{'Jack': 20, 'Mike': 30}
{'Jack': 50, 'Anna': 40}{'Jack': 50, 'Anna': 40}函数参数类型
位置参数/默认参数/关键参数/非固定参数
位置参数:按照参数的顺序传入函数。
def register_stu(name, age, add): print(name, age, add)register_stu('jack', '25', 'beijing')register_stu('25', 'jack', 'beijing')register_stu('beijing', '25', 'jack')jack 25 beijing25 jack beijingbeijing 25 jack
默认参数:默认参数必须在位置参数的后面
def register_stu(name, age, add, country='CN'): print(name, age, add, country)register_stu('jack', '25', 'beijing')jack 25 beijing CN
关键参数:正常情况下,给函数传参数要按顺序,不想按顺序就可以用关键参数,只需指定参数名即可,但记住一个要求就是,关键参数必须放在位置参数之后。
def register_stu(name, age, add, country='CN'): print(name, age, add, country)register_stu(name='jack', age='25', add='beijing')register_stu(add='beijing', name='jack', age='25')register_stu(add='beijing', age='25', name='jack')jack 25 beijing CNjack 25 beijing CNjack 25 beijing CN
非固定参数:若你的函数在定义时不确定用户想传入多少个参数,就可以使用非固定参数。
*args
def stu_register(name, age, *args): # *args 会把多传入的参数变成一个元组形式 print(name, age, args)stu_register('Jack', 31, 'CN', 'Python')Jack 31 ('CN', 'Python')
**kwargs
def stu_register(name, age, *args, **kwargs): # *kwargs 会把多传入的参数变成一个dict形式 print(name, age, args, kwargs)stu_register('Jack', 32)stu_register('Jack', 32, 'CN', 'Python', sex='Male', province='Beijing')Jack 32 () {}Jack 32 ('CN', 'Python') { 'sex': 'Male', 'province': 'Beijing'}
嵌套函数:指的是在一个函数内部调用其他函数。
name = "user"def change_name(): name = "user1" def change_name2(): name = "user2" print('第3层打印', name) change_name2() print('第2层打印', name)change_name()print('最外层打印', name)第3层打印 user2第2层打印 user1最外层打印 user调用change_name2()会提示对象没有定义,即不能直接调用嵌套中的函数。Traceback (most recent call last): File "/Users/yangjian/PycharmProjects/S16/day3/嵌套函数.py", line 21, inchange_name2()NameError: name 'change_name2' is not defined
递归函数
在函数里面调用自己本身,这个函数就是递归函数。
每递归一次相当于往列表里append一个值,退出的时候相当于从列表里pop出一个值
递归特性:
1.必须有一个明确的结束条件
2.每次进入更深一层递归是,问题规模比上次递归都应该有所减少
3.递归效率不高,递归层次过多会导致栈溢出
def calc(n): print(n) #此时n依次地等于10,5,2,1 if int(n/2) > 0: calc(int(n/2)) print(n) #此时n依次地等于1,2,5,10calc(10) 10 52112510
递归函数举例:从1到100亿的数字里查找99
num = range(1, 10000000000, 2)def binary_search(find_num, num_set, count): mid = int(len(num_set)/2) # 拿到里中间的下标 if mid == 0: # 列表值剩下一个了,没必要继续找了 if num_set[mid] == find_num: print('find it...\033[32m%s\033[0m , times %s' % (find_num, count+1)) else: print('can\'t find the num \033[32m%s\033[0m , times %s' % (num_set[0:mid], count+1)) return if num_set[mid] == find_num: print('find it...\033[32m%s\033[0m , times %s' % (find_num, count + 1)) elif num_set[mid] > find_num: print('going to search in left \033[32m%s\033[0m, times %s' % (num_set[0:mid], count+1)) binary_search(find_num, num_set[0:mid], count+1) else: print('going to search in right \033[32m%s\033[0m, times %s' % (num_set[0:mid], count+1)) binary_search(find_num, num_set[mid+1:], count+1)binary_search(99, num, 0)going to search in left range(1, 5000000001, 2), times 1going to search in left range(1, 2500000001, 2), times 2going to search in left range(1, 1250000001, 2), times 3going to search in left range(1, 625000001, 2), times 4going to search in left range(1, 312500001, 2), times 5going to search in left range(1, 156250001, 2), times 6going to search in left range(1, 78125001, 2), times 7going to search in left range(1, 39062501, 2), times 8going to search in left range(1, 19531251, 2), times 9going to search in left range(1, 9765625, 2), times 10going to search in left range(1, 4882813, 2), times 11going to search in left range(1, 2441407, 2), times 12going to search in left range(1, 1220703, 2), times 13going to search in left range(1, 610351, 2), times 14going to search in left range(1, 305175, 2), times 15going to search in left range(1, 152587, 2), times 16going to search in left range(1, 76293, 2), times 17going to search in left range(1, 38147, 2), times 18going to search in left range(1, 19073, 2), times 19going to search in left range(1, 9537, 2), times 20going to search in left range(1, 4769, 2), times 21going to search in left range(1, 2385, 2), times 22going to search in left range(1, 1193, 2), times 23going to search in left range(1, 597, 2), times 24going to search in left range(1, 299, 2), times 25going to search in left range(1, 149, 2), times 26going to search in right range(1, 75, 2), times 27going to search in left range(77, 113, 2), times 28going to search in right range(77, 95, 2), times 29going to search in left range(97, 105, 2), times 30going to search in left range(97, 101, 2), times 31find it...99 , times 32
匿名函数 临时使用的函数,用完就扔,最复杂的运算就是三元运算
def calc(n, y): return n ** yprint(calc(10,12))1000000000000calc2 = lambda n, y: n**yprint(calc2(10, 12))1000000000000for i in map(lambda x: x+1, [1, 2, 3]): print(i)234
高阶函数
特点
1.把一个函数的内存地址传给另外一个函数当做参数
2.把另外一个函数当做返回值返回
def add(x, y, f): return f(x) + f(y)res = add(3, -5, abs)print(res) 8
返回值
要想获取函数的执行结果,就可以用return语句把结果返回
注意:
- 函数在执行过程中只要遇到return语句,就会停止执行并返回结果,so 也可以理解为 return 语句代表着函数的结束
- 如果未在函数中指定return,那这个函数的返回值为None