zoukankan      html  css  js  c++  java
  • 迭代器, 高阶函数(map, filter, reduce, sorted) , 递归函数

    1,  迭代器:

    1.1 可迭代对象: 如果成员中包括__iter__这个方法, 就是可迭代对象,  包括容器类型的数据,range函数,迭代器

    from collections import Iterable,Iterator
    res = isinstance(range(8),Iterable)
    print(res) # True  判断这个数据类型是不是一个可迭代对象
    res1 = isinstance(range(8),Iterator)
    print(res1) # False  判断这个数据类型是不是一个迭代器

    1.2  迭代器定义:  迭代器 : 能被next调用,并不断返回下一个值得对象,叫做迭代器

           概念:  迭代器指的是迭代取值的工具,迭代是一个重复的过程,每次重复都是基于上一次的结果而继续,单纯的重复不是迭代
           特征:  不依赖索引,通过next指针迭代所有数据,一次只取一个,可以大大节省空间,迭代无限量的数据

           如果是迭代器的话就一定是可迭代对象,但是一个可迭代对象不一定是迭代器

    1,3  如何判断一个对象是不是迭代器

           可以使用dir()函数来获取这个对象里面的成员,如果成员中包含__iter__和__next__那这个对象就是一个迭代器
      我们也可以直接打印这个对象, 如果返回一个"list_iterator object"那也可以判断是一个迭代器,也可以用type()来获取, 也可以用isinstance来判断

    list1 = [1,2,"字符",9.9]
    it = iter(list1)
    # 方式一:
    res = "__iter__" in dir(it) and "__next__" in dir(it)
    print(res) # True
    # 方式二:
    print(it) # <list_iterator object at 0x000001F41C4DF1D0>
    print(type(it)) # <class 'list_iterator'>
    # 方式三:
    from collections import Iterator,Iterable
    res = isinstance(it,Iterator)
    print(res) # True

    1.4  迭代器取值方式:

    list1 = [1,2,"字符",9.9]
    it = iter(list1)
    # print(it) # <list_iterator object at 0x000001976367F1D0>
    # 调用迭代器里面的元素:
    # 方式一:  用next()方法
    res = next(it)
    print(res) # 1
    res = next(it)
    print(res) # 2
    res = next(it)
    print(res) # 字符
    res = next(it)
    print(res) # 9.9
    # res = next(it)
    # print(res) # StopIteration  此时迭代器里的元素已经调用完,再调用的话就会报错,因为迭代器是一直向下执行的,不会再回过头去取值
    
    it2 = iter(list1)
    res2 = next(it2)
    print(res2) # 1  如果要重新取迭代器里面的值的话,就要重置这个迭代器,也就是将容器类型重新转化成迭代器
    
    # 方式二: 用for和next配合使用来取值
    list1 = [1,2,"字符",9.9]
    it = iter(list1)
    for i in range(len(list1)):
        res = next(it)
        print(res)  # 这个是将值一次性全部取出来,如果数据量比较大的话,就不推荐这种方式
    
    list1 = [1, 2, "字符", 9.9]
    it = iter(list1)
    for i in range(2):
        res = next(it)
        print(res)  #  这个是只取出迭代器里面的前面两个值,如果数据量比较大,而我们只需要前面某些数据的话,推荐这种方式
    
    # 方式三: 直接使用for循环遍历迭代器里面的值
    list1 = [1, 2, "字符", 9.9]
    it = iter(list1)
    for i in it:
        print(i)  #  遍历出迭代器里的所有值
    
    # 方式四: 将迭代器强转为列表类型
    list1 = [1, 2, "字符", 9.9]
    it = iter(list1)
    list1 = list(it)
    print(list1) # [1, 2, '字符', 9.9]

    2,  高阶函数:  能把函数当做参数传递的就是高阶函数

    2.1  map函数:  map(func,iterabal)

      把iterabal里面的数据一个一个拿出来,放到func函数里面去处理,把处理的结果放到迭代器中,返回迭代器
      func可以值内置函数,也可以是自定义函数
      iterabal是可迭代对象
    2,1,1  map函数小案例:

    # 案例一: 将列表里面的字符串元素变成整型
    #方法一:
    list1 = ["1","2","3","4"]  # ==> [1,2,3,4]
    from collections import Iterator,Iterable
    it = map(int,list1)
    res = isinstance(it,Iterator)
    print(res)  # True 所以map函数取值应该遵循迭代器取值的方法
    list2 = list(it)
    print(list2) # [1, 2, 3, 4]
    # 方法二:
    it = map(lambda n:int(n),list1)
    list2 = list(it)
    print(list2) # [1, 2, 3, 4]
    
    # 案例二:
    # 方法一:
    list1 = [1,2,3,4]  # ==> [1,4,9,16]
    def func1(n):
        return n**2
    it = map(func1,list1)
    list2 = list(it)
    print(list2) # [1, 4, 9, 16]
    # 方法二:
    it = map(lambda n:n**2,list1)
    list2 = list(it)
    print(list2) # [1, 4, 9, 16]
    
    
    # 案例三:
    # dic = {97:"a",98:"b",99:"c"} 给["a","b","c"] => 返回 [97,98,99]
    # 方法一:
    dict1 = {97:"a",98:"b",99:"c"}
    list1 = ["a","b","c"]
    def func1(n):
        for k,v in dict1.items():
            if str(n) in v:
                return k
    it = map(func1,list1)
    res = list(it)
    print(res) # [97, 98, 99]
    # 方法二:
    def func1(n):
        dict2 = {}
        for k,v in dict1.items():
            dict2[v]=k
        return dict2[n]
    it = map(func1,list1)
    res = list(it)
    print(res) # [97, 98, 99]

    2.2  filter函数: 主要是在自定义函数中过滤数据,如果函数返回True,代表保留数据,如果函数返回False,代表舍弃该数据,返回的也是一个迭代器

    2,2,1 filter 函数案例:

    list1 = [1,2,3,4,5,6,7]  # 需要保留奇数
    # 方法一:
    def func1(n):
        if n %2 == 1:
            return True
        else:
            return False
    it = filter(func1,list1)
    list2 = list(it)
    print(list2) # [1, 3, 5, 7]
    # 方法二:
    it = filter(lambda n:True if n%2 == 1 else False,list2)
    list2 = list(it)
    print(list2) # [1, 3, 5, 7]

    2.3  reduce函数: 一次性从可迭代对象中拿出两个值,放到func函数中进行处理,把运算出来的结果再和可迭代对象的第三个值再放到函数中处理,以此类推,最后返回计算后的结果

    2,3,1 reduce()案例

    # 案例一:
    list1 = [5,4,8,8]
    # 方法一:
    def func1(x,y):
        return x*10+y
    from functools import reduce
    res = reduce(func1,list1)
    print(res,type(res)) # 5488 <class 'int'>
    # 方法二:
    from functools import reduce
    res= reduce(lambda x,y:x*10+y,list1)
    print(res,type(res)) # 5488 <class 'int'>
    
    # 案例二:将字符串"123"变成123,不使用int方法
    str1 = "123"
    def dictvar(n):
        dict1 ={"0":0,"1":1,"2":2,"3":3,"4":4,"5":5,"6":6,"7":7,"8":8,"9":9}
        return dict1[n]
    it = map(dictvar,str1)
    list1 = list(it)
    print(list1) # [1, 2, 3]  首先将字符串类型的数字转为整型的数字
    def func1(x,y):
        return x*10+y
    from functools import reduce
    res = reduce(func1,list1)
    print(res,type(res)) # 123 <class 'int'>

    2.4  sorted函数  sorted(iterable,reverse=False,key=函数) 按照自定义或者内置函数对可迭代数据进行排序,其中reverse可以选择是升序还是倒序,返回排序后的列表,功能比sort强大很多, sorted能对所有的容器类型数据进行排列

    2.4.1  使用方式:

    # 按照升序
    tuple1 = (2,83,6,78)
    list1 = sorted(tuple1)
    print(list1) # [2, 6, 78, 83]
    
    # 按照倒序
    set1 = {2,84,52,58,23}
    list1 = sorted(set1,reverse=True)
    print(list1) # [84, 58, 52, 23, 2]
    
    # 按照函数定义的功能排序
    list1 = [26,84,52,1,32]
    def func1(n):
        return n%10
    res = sorted(list1,key=func1)
    print(res) # [1, 52, 32, 84, 26]

    3.  递归函数:  自己调用自己的函数就叫做递归函数,递归层数理论上是1000层,但是实际随电脑配置而定,996层,997层都是有可能的

    3.1  递归函数小案例:  

    def digui1(n):
        print(n)
        if n < 8:
            digui1(n+1)
    digui1(3)  #  最为简单的一种递归操作,在递归函数"回"的过程中没有代码块执行
    
    def digui2(n):
        print(n)
        if n < 8:
            digui2(n+1)
        print(n)
    digui2(3)  #3,4,5,6,7,8,8,7,6,5,4,3
    # 这种情况, digui2(n+1)下面的代码块会先阻塞,等digui2(n+1)上面的代码块执行完后,再依次执行下面的代码
    # 执行下面代码的过程中也是在释放栈帧内存空间
    
    # 用递归写阶乘
    def digui3(n):
        if n < 2:
            return 1
        return n*digui3(n-1)
    res = digui3(5)
    print(res) # 120
    
    # 用递归写斐波那契数列  1,1,2,3,5,8,13,21
    def shulie(n):  # n代表想要打印的第几个斐波那契数
        if n == 1 or n== 2:
            return 1
        return shulie(n-1) + shulie(n-2)
    res = shulie(5)
    print(res)
    
    # 用递归写1到100求和
    def qiuhe(n):
        if n == 1:
            return 1
        return n + qiuhe(n-1)
    res = qiuhe(100)
    print(res)
    # 用递归写n到m求和
    def qiuhe2(n,m):   
        if m == n:
            return n
        return m + qiuhe2(n,m-1)
    res = qiuhe2(-1,2)
    print(res) # 2

    3.2  尾递归:  自己调用自己,并且非表达式,将值放在参数中运行

                 特点:  无论调用多少层,都只占用一层空间,不会有内存溢出的问题,只需要考虑最后一层的结果,但是对解释器是有要求的,目前Cpython解释器并不支持尾递归

    3.2.1 尾递归小案例:

    # 用尾递归写阶乘
    # 方式一:
    def jiecheng(n,endval = 1):
        if n <= 1:
            return endval
        return jiecheng(n-1,endval*n)
    res = jiecheng(5)
    print(res)
    # 方式二: 防止用户乱传参数
    def outter(n):
        def jiecheng(n,endval):
            if n <= 1:
                return endval
            return jiecheng(n - 1, endval * n)
        return jiecheng(n,1)
    res = outter(5)
    print(res)
  • 相关阅读:
    Java 学习资料
    01 html5
    vscode 插件推荐
    08 css高级
    07 css定位
    06 css布局浮动
    05 css盒子
    04 css复合选择器 标签 行高
    03 css字体样式
    02 css基础选择器
  • 原文地址:https://www.cnblogs.com/fdsimin/p/12890853.html
Copyright © 2011-2022 走看看