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)
  • 相关阅读:
    loaded some nib but the view outlet was not set
    指标评比
    IOS DEVELOP FOR DUMMIES
    软件测试题二
    javascript select
    DOM节点类型详解
    mysql操作
    UVA 10055
    solutions for 'No Suitable Driver Found For Jdbc'
    解决git中文乱码问题
  • 原文地址:https://www.cnblogs.com/fdsimin/p/12890853.html
Copyright © 2011-2022 走看看