局部变量
函数中的变量用的是就近原则,谁离得近就用谁的值
在函数内部定义的变量,作用范围就是这个函数内部,其他函数是没法用这个局部变量的
不调用,就不存在,调用完以后,这个变量就不能使用了(从栈中出去了)
全局变量
作用到整个文件,可以在所有的函数中进行访问,并且是在函数外边定义的变量
并且在有全部变量和局部变量重名的时候,在函数中,输出这个变量的时候, 函数输出的值会采取就近原则
c = 8
def a():
c = 7
print(c)
a() #7
全部变量的修改
如果想修改全局变量.就要在一个函数中声明 global ,告诉这个函数要修改全局变量
全局变量和局部变量的查看
globals() 查看所有的全局变量
locals() 查看所有的局部变量
return
函数返回多个值
一个函数中可以有多个return语句,但是只要有一个return语句被执行到,那么这个函数就会结束了,因此后面的return没有什么用处
def get_num(a, b):
c = a + b
d = a - b
return (c, d, 3)
print(get_num(12, 5)) #(17, 7, 3)
f = get_num(12, 5) # 可以用值接收
a, b, c = get_num(12, 5) # 这里输出的是(17, 7, 3)...保证这里的值和return中的返回值在数量上是一样的
print(a) #17
print(b) #7
def show():
return {"name": "胡冠雨", "age": 30, "sex": "男"}
name, age, sex = show() #这个也是拆包
print(name)
print(age)
print(sex)
这样返回的是偶是一个元组
return后面可以是元组,列表、字典等,只要是能够存储多个数据的类型,就可以一次性返回多个数据。
def divid(a, b):
shang = a//b
yushu = a%b
return shang, yushu #默认是元组
result = divid(5, 2)
print(result) # 输出(2, 1)
拆包
字典拆包查出来的是key 而不是键值对
- 拆包时要注意,需要拆的数据的个数要与变量的个数相同,否则程序会异常
- 除了对元组拆包之外,还可以对列表、字典等拆包
a, b = {"m":11, "n":22} # 取出来的是key,而不是键值对 a 为'm' b 为'n'
a, b = [11, 22] # a为11 ,,b为22
a, b = (11, 22) # a为11 ,,b为22
函数参数
缺省函数
形参汇总,默认有值的参数,就是缺省函数,并且缺省函数必须写在最后
传值就用传入的值,没传值,就用默认定义的,传值了,默认参数就会被替换
- 在形参中默认有值的参数,称之为缺省参数
- 注意:带有默认值的参数一定要位于参数列表的最后面
def get_sum(a, b, c=7): #c为缺省参数
return a + b + c
print(get_sum(5, 6))
不定长参数
需要一个函数能处理比当初声明时更多的参数, 这些参数叫做不定长参数,声明时不会命名
*args传入列表,元组,**kwargs传入字典
def functionname([formal_args,] *args, **kwargs):
"""函数_文档字符串"""
function_suite
return [expression]
-
加了星号(*)的变量args会存放所有未命名的变量参数,args为元组
-
而加**的变量kwargs会存放命名参数,即形如key=value的参数, kwargs为字典.
-
如果很多个值都是不定长参数,那么这种情况下,可以将缺省参数放到 *args的后面, 但如果有*kwargs的话,*kwargs必须是最后的
def sum_nums_3(a, *args, b=22, c=33, **kwargs):
print(a)
print(b)
print(c)
print(args)
print(kwargs)
sum_nums_3(100, 200, 300, 400, 500, 600, 700, b=1, c=2, mm=800, nn=900)
"""
100
1
2
(200, 300, 400, 500, 600, 700)
{'mm': 800, 'nn': 900} """ #最后的mm 如果是字符串就要加""
可变,不可变类型
- 所谓可变类型与不可变类型是指:数据能够直接进行修改,如果能直接修改那么就是可变,否则是不可变
- 可变类型(修改数据,内存地址不会发生变化)有: 列表、字典、集合
- 不可变类型(修改数据,内存地址必定发生变化)有: 数字、字符串、元组
递归函数
就是自己调用自己,不给出口就会是死循环,然后栈溢出,报错
特点: 必须有一个出口, 可以是一个判断语句,也可以是一个值
# n! = 1 * 2 * 3 * ... * n
def cal(num):
result, i = 1, 1
while i <= num:
result *= i #这个就是利用的sum*=i 算是很简单的
i += 1
return result
print(cal(3))
#用递归递归递归递归递归递归递归递归递归递归递归递归递归
def factorial(num):
result = 1
if num == 1: #计算的值,,也是一个关键点 如果num==1,,就会输出一个1
return 1
result = num * factorial(num -1)
#结果为 factorial(4) = 4*factorial(3) = 4*3*factorial(2) = 4*3*2*factorial(1) =4*3*2*1=24
return result
print(factorial(4))
匿名函数
没有名字的函数 变量 = lanmbda 什么参数 : 干什么
lambda 参数列表: 运算表达式
get_sum = lambda a,b : a+b
#def get_sum(a, b): #上面那一句就是这两句的缩写
#return (a + b)
print(get_sum(1,2)) #3
Lambda函数能接收任何数量的参数但只能返回一个表达式的值
匿名函数可以执行任意表达式(甚至print函数),但是一般认为表达式应该有一个计算结果供返回使用。所以最好不要在lanmbda中写入print函数
python在编写一些执行脚本的时候可以使用lambda,这样可以接受定义函数的过程,比如写一个简单的脚本管理服务器。
快速排序
nums = [3, 1, 6, 9, 8, 2, 4, 5, 7]
def quick_sort(low, high, nums): # low最左边,high最右边
# 递归的出口
if low >= high: #每一轮递归结束的出口,,i和j相撞了
return
i = low #这里的i j都是表示的下标
j = high
base = nums[low] #base值在左边第一个数字
while i < j:
# j动
while i < j and nums[j] >= base: #如果j 还在i 的右边,,并且nums[j]所对应的值大于base值
j -= 1 #j就继续往左边走,,也就是j的值变小
#j停了以后, i动
while i < j and nums[i] <= base:#如果i在j的左边,并且nums[i]所对应的值小于base值
i += 1 ##i就继续往右边走,,也就是i的值变大
# 如果i依然小于j,证明i和j没有撞到,就交换元素
if i < j:
nums[i], nums[j] = nums[j], nums[i]
# 如果i和j没有走上面这个while判断 ,那就证明 i和j相遇了 相遇之后 交换基准值和i和j相遇的下标对应的数值
nums[low] = nums[i] #注意这里要用空杯思想,,不能直接用a , b = b, a
nums[i] = base
#替换后,已原基准值为一条线,分为左右两个,分开循环
quick_sort(low, i - 1, nums) # 左边的一半,这里随便使用i-1 还是j-1 ,因为此时的i j指向的同一个地方
quick_sort(i + 1, high, nums)# 右边的一半
quick_sort(0, len(nums) - 1, nums) #调用快拍的递归,因为i j为下标,所以要len(nums) - 1,,要在nums列表中执行
print(nums)
函数作为参数传递
show = lambda a, b: a + b
def get_sum(a, b, opt):
print(opt(a, b))
get_sum(1, 2, show)
students = [
{'name': 'zhangsan', 'age': 18, 'score': 92},
{'name': 'lisi', 'age': 20, 'score': 90},
{'name': 'wangwu', 'age': 19, 'score': 95},
{'name': 'jerry', 'age': 21, 'score': 98},
{'name': 'chris', 'age': 17, 'score': 100},
]
students.sort(key=lambda i: i['score'], reverse=True)
print(students)
new_students = sorted(students, key=lambda ele: ele['score'], reverse=True)
print(new_students)
内置函数
sorted 进行排序的
filter 过滤操作
map映射操作
reduce 过整合操作
nums = [5, 1, 3, 7, 9, 8, 2, 6] # 过滤 ,取模2 ==0的
new_nums = filter(lambda x: x % 2, nums)
print(list(new_nums)) # 无法直接输出new_nums,,因为是一个.... [5, 1, 3, 7, 9]
new_nums = map(lambda x: x ** 2, nums) # map映射 x的平方
print(list(new_nums)) #[25, 1, 9, 49, 81, 64, 4, 36]
red = reduce(lambda x, y: x * y, nums) # reduce 整合,,就是相乘 当然也可以吧*改成其他符号
print(red) # 90720
插入排序
# 插入排序
nums = [3, 1, 6, 9, 8, 2, 4, 5, 7]
# 做遍历操作
# 从1号索引开始遍历 遍历到最后
# 只要i索引比前面的值小 就交换位置 交换完毕之后 不要忘了将索引值减1 再次重复刚才的操作 直到索引为0就不再动
def insert_sort(nums):
# 先获取nums列表的长度
length = len(nums)
# 开始遍历
for i in range(1, length):
j = i - 1
while j >= 0 and nums[j] > nums[j + 1]:
nums[j], nums[j + 1] = nums[j + 1], nums[j]
j -= 1
insert_sort(nums)
print(nums)
递归函数的几个习题
# 求 1 -- 100的所有的数的和 不适用for循环 递归去做
def get_sum(num):
if num == 1:
return 1
else:
return num + get_sum(num - 1) #100+99+98 每调用一次get_sum(num - 1),就会出现一个num - 1,加起来就可以了
print(get_sum(100))
#斐波那契数列 兔子问题
# 1 1 2 3 5 8 求第12个月 一共有多少对兔子
def get_rabbit(month):
if month == 1 or month == 2: #第一个月或者第二个月都只有返回1
return 1
else:
return get_rabbit(month - 1) + get_rabbit(month - 2)
#这里是比如month=5 ,就会有,return get_rabbit(4)+return get_rabbit(3)
# return get_rabbit(4)= return get_rabbit(3)+return get_rabbit(2)
# return get_rabbit(3)=return get_rabbit(2)+return get_rabbit(1)
"""所以会有
return get_rabbit(5) =
get_rabbit(4) + get_rabbit(3) =
get_rabbit(3) + get_rabbit(2) + get_rabbit(2) + get_rabbit(1) =
get_rabbit(2) + get_rabbit(1) + get_rabbit(2) + get_rabbit(2) + get_rabbit(1) = 5
其中的get_rabbit(2) 和 get_rabbit(1) 等于1 就有 get_rabbit(5) = 1+1+1+1+1 = 5
这种递归就是这样一层一层剥下来,剥到最终的if定义的数值中
"""
print(get_rabbit(12))
#网上的
# Filename : test.py
# author by : www.runoob.com
def recur_fibo(n):
"""递归函数
输出斐波那契数列"""
if n <= 1:
return n
else:
return(recur_fibo(n-1) + recur_fibo(n-2))
# 获取用户输入
nterms = int(input("您要输出几项? "))
# 检查输入的数字是否正确
if nterms <= 0:
print("输入正数")
else:
print("斐波那契数列:")
for i in range(nterms):
print(recur_fibo(i))
#猴子吃桃子问题
#一只猴子第一天摘了一堆桃子 然后吃了一半零1个 到第10天的时候 发现桃子还剩1个 求第一天一共摘了多少桃子
def get_tao(day):
if day == 10:
return 1
else:
return (get_tao(day + 1) + 1) * 2 #公式就是 (i+1)*2 for i in range(1,11)
print(get_tao(1))