9.变量,return,缺省和不定长参数,递归函数,匿名函数,内置函数,快速排序和插入排序,斐波那契数列兔子问题,猴子吃桃子问题

局部变量

函数中的变量用的是就近原则,谁离得近就用谁的值

在函数内部定义的变量,作用范围就是这个函数内部,其他函数是没法用这个局部变量的

不调用,就不存在,调用完以后,这个变量就不能使用了(从栈中出去了)

全局变量

作用到整个文件,可以在所有的函数中进行访问,并且是在函数外边定义的变量

并且在有全部变量和局部变量重名的时候,在函数中,输出这个变量的时候, 函数输出的值会采取就近原则

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))
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值