Day09 - 迭代器&生成器,匿名函数,递归,高阶函数

在这里插入图片描述

迭代器和生成器

迭代
  1. 迭代对象指可以被for循环遍历的对象,迭代是指遍历的过程
  2. 可迭代对象有两个 - 容器和迭代器,迭代器又有生成器分支
迭代器 - iterator
  1. 性质

    • 迭代器中的元素无法被print打印
    • 迭代器中元素个数无法用len方法查看
    • 迭代器 - iterator
    • 迭代类似数据结构中的队列,具有先进先出的特性,元素被取出后即消失
    • iter方法可将任何容器型数据类型转为迭代器
    str1 = 'hello'
    str1_iter = iter(str1)  # 将字符串类型数据转为迭代器
    print(str1_iter, type(str1_iter))  
    # 打印结果为<str_iterator object at 0x103425fd0> <class 'str_iterator'>
    
    list1 = [1, 2, 3]
    list_iter = iter(list1)  # 将列表转为迭代器
    print(list_iter, type(list_iter))
    # 打印结果为<list_iterator object at 0x103425f40> <class 'list_iterator'>
    
如何获取迭代器中的元素
  1. 方法1 - 用for循环遍历

  2. 方法2 - next( )

    # 用for循环遍历
    for i in str1_iter:
      print(i)  # 每次输出一个元素
    # 输出结果为
    h
    e
    l
    l
    o
    
    # next() - 一个一个取
    print(next(str1_iter))  # 输出结果为h
    
迭代器能做什么
  • 迭代器的使用,能使元素被取出,释放内存,让程序的内存占用更小
生成器 - generator
  1. **性质
    ** 使用生成器的目的是生成迭代器,可以说生成器是迭代器,但迭代器不一定生成器

    • 生成器为一个函数
    • 函数不会在调用生成器时执行,只有在获取元素时生成器才执行
    • 获取一个元素才能够让生成器函数执行一次
    • 生成器函数的返回结果用yield代替return
    • yield执行几次,生成器就生成几个元素
    # 定义一个生成器函数
    def myGener():
      print('123')
      yield 100
      yield 200
      yield 300
      if 100 > 200:
        yield 300
      return 1
    	yield 400
    
    f = myGener()
    print(f)  # 调用时函数不执行,无输出结果
    print(next(f))  # 输出元素100
    for i in f:
      print(i)  # 打印剩余元素,输出200和300
    
yield和return区别
  • 当return被触发时,执行立即结束,yield则不会结束函数执行

  • return和yield都可将函数的结果返回到外部

  • return和yield后面跟的都是表达式

    # 练习:使用生成器创建python001-python999学号
    def stu_id():
      for i in range(1, 1000):
        yield f'python{j:0>3}'
    
    f = stu_id()
    print(next(f))  # 打印结果为python001
    for _ in range(100):
      print(next(f))  # 打印结果为python002-python101
    # 接着上次的打印,从python002打印100个,到python101结束
    

匿名函数

  1. 概念 - 用lambda表达式简化的函数

  2. 原理 - 普通函数和匿名函数类似于单分支结构和三目运算符的关系

  3. 匿名函数有严格的固定语法,是普通函数的语法糖(在原有的语法上做简化,能提高代码的可读性,但不影响功能)

    # 计算两数字的和
    def numSum(num1, num2):  # 普通方法
      return num1 + num2
    print(numSum(10, 20))  # 输出结果为30
    
    # lambda方法
    numSumLambda = lambda num1, num2: num1 + num2
    print(numSumLambda(10, 20))  # 输出结果为30
    
  4. 匿名函数lambda语法

    # 函数名 = lambda 形参: 返回值
    # 函数名(实参)
    
    # 练习:使用匿名函数计算1-100的和
    totalLambda = lambda start, end: sum([i for i in range(start, end+1)])
    print(totalLambda(1, 100))  # 输出结果为5050
    
  5. 并不是所有的普通函数都可以转为匿名函数

    # 练习:使用匿名函数判断年份是否为闰年
    isLeapYear = lambda year: [f'{year}年为闰年' if year % 400 == 0 or (if year % 4 == 0 and year % 4 != 0) else f'{year}年不为闰年']
    print(isLeapYear(2000))  # 输出结果为2000年为闰年
    

递归

  • 递归是一种循环思想
  • 函数的执行是一个相互调用的过程,递归是一种特殊的函数调用,为自己调用自己
迭代(递推)思维和递归思维
  • 递推思维 - 根据已有的数据来推算规律 (正向推算),例如斐波那契数列

  • 递归思维 - 根据规律逆向推算

  • 递归虽为循环思想,但要注意循环结束的条件,不然会造成死循环

    # 递归思想
    def fib(N):
      if N == 1 or N == 2:  # 斐波那契数列的前两位为1
        return 1
      else:
        return fib(N - 1) + fib(N - 2)
    print(fib(9))
    
如何写出递归思想的代码
  • 知道最终结果的计算规律

  • 从需要算的结果往前推

  • 了解递归的结束条件

    # 练习:用递归计算N的阶乘
    def factorial(n):
      if n == 1:
        return 1
      else:
        return n * factorial(n-1)
    
    print(factorial(10))
    
  • ****能用循环解决的问题就能使用递归解决

  • 若计算量较大,使用递归时有拓栈和压栈的过程,拓栈时内存容易溢出****

  • 使用for循环不用考虑内存溢出

  • 栈的特性是**’ 先进后出 '**

高阶函数

  • 定义 - 将一个函数当作另一个函数的参数

    def func1():
      pass
    
    def func2(func):
      print('这是另一个函数')
      func()
    func2(func1)  # 打印结果为'这是另一个函数'
    
  • Python常用高阶函数: max、min、sorted、map、reduce

    # max、min调取容器中的最大/最小元素
    nums = [10, 55, 67, 666, 900]
    print(max(nums))
    
    # max(容器, key=函数): 按照函数定义的方式获取容器中的最大值
    # 按照数字中个位数的大小取值
    def unitNum(num):
      return num % 10
    
    print(max(nums, key=unitNum))  # 打印结果为67
    print(max(nums, key=lambda num: num % 10))
    # 打印结果为67
    print(min(nums, key=unitNum))  # 打印结果为10
    
    # sorted(容器, key=函数): 按照函数指定的形式对容器中元素排序
    nums = [10, 55, 67, 666, 900]
    print(sorted(nums, key=lambda num: num % 10))
    #  打印结果为[10, 900, 55, 666, 67],按照个位数从小到大
    
    # reduce: 对传递的容器中的每个元素做累计
    # 语法: reduce(函数, 容器, 初始值)
    # 函数要求:
    # a. 函数有两个形参,第一个指向初始值,第二个指向容器中每个元素
    # b. 必须有返回值
    from functools import reduce
    # 对列表中元素做积累
    nums = [10, 55, 67, 666, 900]
    print(reduce(lambda total * num, nums, 1))
    # reduce性能明显不及for循环,但表达方式更优雅/可读性更强
    
    # map(): 根据容器产生一个新的序列
    # 语法: map(函数, 容器1, 容器2, ....)
    # 函数要求:
    # a. 函数有N(容器数量)个形参
    # b. 有返回值
    # map函数产生的结果是一个可迭代对象,可以将可迭代对象使用构造器语法转换为列表、元组、集合等容器
    names = ['小明', '小王', '小李']
    chinese = [90, 95, 80]
    english = [60, 70, 80]
    map_iter = map(lambda a, b, c: {'name': a, 'chinese': b, 'english': c}, names, chinese, english)
    print(map_iter)
    # for i in map_iter:
    #  print(i)
    print(list(map_iter))
    
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值