Day 12 函数使用之进阶

Day 12 函数使用之进阶

几点总结

  • 函数式编程: 遇到问题首先想到的有没有一个函数能够解决这个问题,有直接调用,没有则创建

  • return作用,将数据作为返回值返回,提前结束函数(执行函数体的时候,遇到return函数直接结束)相当于循环中的break,return只能在函数体中使用

    def func3(n):
        # n = 5
        for x in range(1, n):
            if x % 3 == 0:
                return x
            print(f'x:{x}')
    print(func3(5))   #x : 1,x : 2,3   其中3是返回值,
    
  • 列表中的元素转换成字符串时,产生一个一个单一的字符

  • eval()函数可用性很强

变量作用域

  • 变量作用域不同,可将变量分为全局变量和局部变量

  • 全局变量: 没有定义在函数或者类中的变量默认都是全局变量,从定义开始到程序结束都可以使用,函数中也可以使用全局变量

    a = 100   # 全局变量
    for i in range(5):
        print("a:", a)
    
  • 局部变量: 定义在函数中的变量,就是局部变量,从定义开始,到函数调用结束,调用函数时,才能使用局部变量,形式参数就是局部变量,只能在函数里面用

  • 函数调用的时候申请内存,存储变量,调用结束销毁内存,输出返回值,返回值存储在全局栈区间

    全局变量和局部变量存储原理
    全局变量默认保存在全局栈区间,
    调用函数的时候系统回自动为这个函数创建一个临时栈区间,用来保存函数中产生的数据
    局部变量就是保存在临时栈区间中的,函数对应的临时栈区间会在函数调用结束时自动释放
    
  • 在函数中可以通过关键字 global 修改局部变量的保存方式,将局部变量保存在全局变量中
    global

    name  = "笑话"
    def func(m):
        global n
        n = 1000  #在函数内部定义全局变量
        print("函数里面m=", m)
        print("函数里面n=", n)
        global  name
        name = "瞎画画"  #在函数内部修改全局变量
    func(100)
    n = 10
    print("name:", name)  
    

匿名函数

  • 函数名 = lambda 形参列表 : 返回值

    sum_2 = lambda num1=1, num2=2: num1 + num2
    """
    变量
    返回值
    即被定义,也被使用
    """
    
    
    """
    匿名函数即被定义,也被使用
    匿名函数的形参至少一个
    匿名函数的调用和普通函数一样
    匿名函数不能使用类型说明,无默认值的类型说明,在匿名函数中不能使用
    主要时因为,语法格式相互矛盾
    """
    

高阶函数

  • 实参高阶函数

    # 1. 实参高阶函数
    # 函数的参数是函数的函数就是实参高阶函数
    # 给参数是函数的参数传参:a.使用普通函数函数名;b.使用匿名函数
    # 重点:掌握系统或者第三方库提供的实参高阶函数的用法
    # 常见的实参高阶:max、min、sorted、列表.sort、map、reduce
    
  • max( )) 高阶函数

    """
    max(序列)     直接比较序列中元素的大小,求最大值
    max(序列,key = 函数)    按照函数指定的规则比较序列中元素大小,获取最大值
    
    函数要求:
    有且只有一个参数(这个参数代表序列中的每一个元素)序列是比较的序列,唯一需要注意点,参数是序列中的每一个元素
    有一个返回值(返回值就是比较对象),,,返回值代表比较对象,按照什么标准或者属性来进行排序,比较
    
    """
    
    # 练习1:求list1中长度最长的字符串
    list1 = ['你好', 'hello', 'how are you', 'thank you! and you?', '好好学习,天天向上']
    print(max(list1, key=lambda i: len(i)))
    
    # 练习2:求nums中十位数最小的元素
    nums = [92, 129, 37, 99, 150, 501]
    print(max(nums, key=lambda i: i // 10 % 10))
    
    # 练习3:将所有的学生按照年龄值从小到大排序
    students = [
        {'name': 'stu1', 'age': 18, 'score': 90},
        {'name': 'stu2', 'age': 22, 'score': 98},
        {'name': 'stu3', 'age': 25, 'score': 78},
        {'name': 'stu4', 'age': 19, 'score': 81},
        {'name': 'stu5', 'age': 20, 'score': 92}
    ]
    print(sorted(students, key=lambda i: i["age"] % 10, reverse=True))
    
    # 练习4:求nums中各个位之和最大的元素
    nums = [123, 78, 90, 201, 192, 330]
    # print(max(nums, key=lambda i: sum(int(j) for j in str(i))))
    
    print(max(nums, key=lambda i: eval("+".join(str(i)))))  # 用评估函数对字符串进行拼接,最后转换成可操作的表达式,去掉引号
    
    # i = 123
    # j = str(i)
    # print(j)
    # print(list(j))
    
  • map () 高阶用法

    """
    基于原序列中的元素创建一个新的序列      通过函数描述的规则,基于原序列的元素,创建新的序列
    map(函数,序列)
    
    函数的要求:
    有且只有一个参数,,代表后面序列中的每个元素
    有一个返回值,返回值就是新序列中的元素
    
    map(函数,序列,序列)
    
    函数的要求:
    有且只两个参数,,代表后面序列中的每个元素
    有一个返回值,返回值就是新序列中的元素
    
    """
    
    # 练习1:获取names中每个人的姓
    names = ['何晓东', '张三', '李四', '王五', '王二', '赵六']
    family_name = map(lambda i: i[0], names)
    print(list(family_name))
    
    
    # 练习2:   i , j是序列中的直接元素
    students = [
        {'name': 'stu1', 'age': 18, 'score': 90},
        {'name': 'stu2', 'age': 22, 'score': 98},
        {'name': 'stu3', 'age': 25, 'score': 78},
        {'name': 'stu4', 'age': 19, 'score': 81},
        {'name': 'stu5', 'age': 20, 'score': 92}
    ]
    subjects = ['电子信息', '金融数学', '园林设计', '经济', '计算机软件']
    
    # ['电子信息-stu1', '金融数学-stu2',....]
    result = map(lambda i, j: f"{j}-{i['name']}", students, subjects)
    print(list(result))
    
  • reduce() 高阶函数

    """
    将序列中的元素合并成一个数据
    基于原序列中所有的元素,,得到一个数据
    
    reduce(函数,序列,初始值)   -   按照函数指定的规则
    函数的要求:
    有且只有两个参数
    第一个参数指向初始值,第二个参数代表序列中的每个元素
    需要一个返回值,(返回值就是合并规则)
    
    初始值:  累计就和  初始值是0
            累计求乘积  初始值是1
            字符串合并,初始值是空串
    """
    
    from functools import reduce
    nums = [12, 301, 40, 55, 112]
    # 求个位数的和
    result = reduce(lambda i, j: i + eval(str(j)[-1]), nums, 0) # 用eval函数评估字符串,将其转换成数字
    print(int(result))
    # 123014055112
    result = reduce(lambda i, j: i + eval(str(j)[-1]), nums, 0)
    

迭代器

  • 是一个序列,无法直接创建迭代器,只能将其他序列转换成迭代器

    """
    特点:
    打印迭代器时,无法查看元素有哪些
    无法通过len()获取迭代器中元素的个数
    使用迭代器中的元素,必须将元素从迭代器中取出来.取走的元素会从迭代器中永远消失,用一个就少一个
    任何数据都可以作为迭代器的元素
    """
    
    # 创建迭代器
    i1 = iter("abc")
    i2 = iter(["abc", 1, 2, 3, 5])
    print(i1)
    print(i2)
    
    """
    获取单个元素
    next(迭代器)     获取迭代器中最上面的元素
    转换成列表也会使迭代器中的元素,消失
    
    遍历: 也会取到迭代器中的元素,迭代器会消失
    for 变量 in 迭代器:
        操作   
    执行完,迭代器就被掏空
    """
    
    i2 = iter(["abc", 1, 2, 3, 5])
    for i in i2:
        print(i)
    print(list(i2)) #[]
    
    i2 = iter(["abc", 1, 2, 3, 5])
    print(next(i2))  # abc
    list1 = list(i2)
    print(list1)  # [1, 2, 3, 5]
    print(list(i2))  # []
    

作业

  1. 写一个匿名函数,判断指定的年是否是闰年 (先直接用普通函数)

    """
    写一个匿名函数,判断指定的年是否是闰年 (先直接用普通函数) 
    """
    
    
    #
    # leap_year = lambda i: (i % 4 == 0 and i % 100 != 0) or i % 400 == 0 # 给匿名函数返回值时,命名时会有警告
    # print(leap_year(2023))
    
    #
    # def leap_year(year):
    #     return (year % 4 == 0 and year % 100 != 0) or year % 400 == 0
    #
    #
    # print(leap_year(2023))
    leap_year = lambda i: (i % 4 == 0 and i % 100 != 0) or i % 400 == 0# 给匿名函数返回值时,命名时会有警告
    print(leap_year(2023))
    
    # 匿名函数变量本质上是形式参数,需要传入参数值
    
  2. 写一个函数将一个指定的列表中的元素逆序( 如[1, 2, 3] -> [3, 2, 1])(注意:不要使用列表自带的逆序函数)

    """
    写一个函数将一个指定的列表中的元素逆序( 如[1, 2, 3] -> [3, 2, 1])(注意:不要使用列表自带的逆序函数)  
    """
    list1 = [1, 2, 3]
    
    
    def exchange(list_one=[]):
        new_list = []
        for i in range(-1, -len(list_one) - 1, -1):  # 所有的排序都是从小到大
            print(i)
            new_list.append(list_one[i])
        return new_list
    
    
  3. 编写一个函数,计算一个整数的各位数的平方和

"""
编写一个函数,计算一个整数的各位数的平方和
例如: sum1(12) -> 5(1的平方加上2的平方)    sum1(123) -> 14
"""
num = 123


def product(num_one):
    return eval("**2+".join(str(num_one)) + "**2")


print(product(num))
  1. 求列表 nums 中绝对值最小的元素
"""
求列表 nums 中绝对值最小的元素
例如:nums = [-23, 100, 89, -56, -234, 123], 最小值是:-23
"""
nums = [-23, 100, 89, -56, -234, 123]
result = min(nums, key=lambda i: i ** 2)
print(result)
  1. 已经两个列表A和B,用map函数创建一个字典,A中的元素是key,B中的元素是value

    """
    已经两个列表A和B,用map函数创建一个字典,A中的元素是key,B中的元素是value
    A = ['name', 'age', 'sex']
    B = ['张三', 18, '女']
    新字典: {'name': '张三', 'age': 18, 'sex': '女'}
    """
    A = ['name', 'age', 'sex']
    B = ['张三', 18, '女']
    C = map(lambda i, j:(i,j), A, B)
    print(dict(C))
    
  2. 已经三个列表分别表示5个学生的姓名、学科和班号,使用map将这个三个列表拼成一个表示每个学生班级信息的的字典

    """
    已经三个列表分别表示5个学生的姓名、学科和班号,
    使用map将这个三个列表拼成一个表示每个学生班级信息的的字典
    names = ['小明', '小花', '小红', '老王']
    nums = ['1906', '1807', '2001', '2004']
    subjects = ['python', 'h5', 'java', 'python']
    结果:{'小明': 'python1906', '小花': 'h51807', '小红': 'java2001', '老王': 'python2004'}
    """
    names = ['小明', '小花', '小红', '老王']
    nums = ['1906', '1807', '2001', '2004']
    subjects = ['python', 'h5', 'java', 'python']
    result = map(lambda i, j, k: (f"{i}", f"{j}{k}"), names, nums, subjects)
    print(dict(result))
    
  3. 已经一个列表message, 使用reduce计算列表中所有数字的和

    """
    已经一个列表message, 使用reduce计算列表中所有数字的和
    message = ['你好', 20, '30', 5, 6.89, 'hello']
    结果:31.89
    """
    message = ['你好', 20, '30', 5, 6.89, 'hello']
    from functools import reduce
    def num(list_one = []):
        new_list = []
        for i in list_one:
            if type(i) == int or type(i) == float:
                new_list.append(i)
            else:
                count = 0
                for j in i:
                    if "0" <= j <= "9":
                        print(count)
                        count +=1
                    else:
                        break
                if count == len(i):
                    new_list.append(eval(i))
        return new_list
    print(num(message))
    
    result = reduce(lambda k,item: k+item, num(message),0)
    print(result)   # 61.89
    
    
    
    from functools import reduce
    
    message = ['你好', 20, '30', 5, 6.89, 'hello']
    result = reduce(lambda i, j: i + j if type(j) == int or type(j) == float else i, message, 0)
    print(result)
    
  4. 已经列表points中保存的是每个点的坐标(坐标是用元组表示的,第一个值是x坐标,第二个值是y坐标)

    points = [
      (10, 20), (0, 100), (20, 30), (-10, 20), (30, -100)
    ]
    

    1)获取列表中y坐标最大的点

    2)获取列表中x坐标最小的点

    3)获取列表中距离原点最远的点

    4)将点按照点到x轴的距离大小从大到小排序

    """
    已经列表points中保存的是每个点的坐标(坐标是用元组表示的,第一个值是x坐标,第二个值是y坐标)
    points = [
      (10, 20), (0, 100), (20, 30), (-10, 20), (30, -100)
    ]
    
    
    
    ```python
    points = [
      (10, 20), (0, 100), (20, 30), (-10, 20), (30, -100)
    ]
    ```
    
    1)获取列表中y坐标最大的点
    
    2)获取列表中x坐标最小的点
    
    3)获取列表中距离原点最远的点
    
    4)将点按照点到x轴的距离大小从大到小排序
    
    """
    points = [
      (10, 20), (0, 100), (20, 30), (-10, 20), (30, -100)
    ]
    #1)获取列表中y坐标最大的点
    print(max(points,key=lambda i :i[-1]))
    #2)获取列表中x坐标最小的点
    print(min(points,key=lambda i :i[0]))
    #3)获取列表中距离原点最远的点
    print(max(points,key=lambda i :i[0]**2+i[-1]**2))
    #4)将点按照点到x轴的距离大小从大到小排序
    print(sorted(points,key=lambda i :i[0]**2+i[-1]**2))
    
  5. 封装一个函数完成斗地主发牌的功能。

"""
封装一个函数完成斗地主发牌的功能。
"""
from random import shuffle
colors = ['♠', '♣', '♥', '♦']
numbers = ['A', '2', '3', '4', '5', '6', '7', '8', '9', '10', 'J', 'Q', 'K']
J = 11
Q = 12
K = 13
A = 14
g = 16
l = 15
X = 10
pukes = [i + k for i in colors for k in numbers]
print(len(pukes))
pukes.extend(["big", "small"])
print(pukes)
# 实现发牌
def deal(pukes: list):
    shuffle(pukes)
    print(pukes)
    pukes = iter(pukes)
    for i in range(3):
        print(i)
        player = []
        for j in range(17):
            player.append(next(pukes))
        print(f"player{i + 1}的牌是:",
              sorted(player, key=lambda x: eval(x[-1]) + 10 if eval(x[-1]) == 0 else eval(x[-1])))
deal(pukes)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值