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

    迭代器

    1.迭代器的定义: 能被next调用,并不断返回下一个值的对象,叫做迭代器(对象)

    2.迭代器的概念:

      迭代器指的是迭代取值的工具,迭代是一个重复的过程,
      每次重复都是基于上一次的结果而继续的,
      单纯的重复并不是迭代

    3.迭代器的特征: 并不依赖索引,而通过next指针迭代所有数据,一次只取一个值,大大节省空间

    4.dir: 获取当前类型对象中的所有成员

    其中,里面有一个魔术方法,叫做__iter__方法,

    __iter__方法用来判断是否是可迭代性数据

    setvar = {"a","b","c","d"}
    lst = dir(setvar) # 获取setvar对象中的所有成员
    print(lst)
    '''
    ['__and__', '__class__', '__contains__', '__delattr__',
    '__dir__', '__doc__', '__eq__', '__format__', '__ge__', 
    '__getattribute__', '__gt__', '__hash__', '__iand__', '__init__',
    '__init_subclass__', '__ior__', '__isub__', '__iter__', '__ixor__', 
    '__le__', '__len__', '__lt__', '__ne__', '__new__', 
    '__or__', '__rand__', '__reduce__', '__reduce_ex__', '__repr__',
    '__ror__', '__rsub__', '__rxor__', '__setattr__', '__sizeof__', 
    '__str__', '__sub__', '__subclasshook__', '__xor__', 'add',
    'clear', 'copy', 'difference', 'difference_update', 'discard',
    'intersection', 'intersection_update', 'isdisjoint', 'issubset',
    'issuperset', 'pop', 'remove', 'symmetric_difference', 
    'symmetric_difference_update', 'union', 'update']
    '''

    5.关于迭代器,需要注意的点:

    for 循环能够遍历一切可迭代性数据的原因在于,底层调用了迭代器,通过next方法中的指针实现数据的获取

    可迭代对象(不能够被next直接调用)  -> 迭代器(可以被next直接调用的过程) 

    一个可迭代对象不一定是迭代器

    一个迭代器就一定是一个可迭代对象

    6.定义一个迭代器

    定义迭代器需要使用iter()方法

    setvar = {"a","b","c","d"}
    it = iter(setvar) # 将可迭代对象setvar变成了迭代器
    print(it) # <set_iterator object at 0x000002142D1108B8>

    7.判断一个迭代器

    迭代器必须要有__iter__方法和__next__方法

    res = "__iter__" in dir(it) and "__next__" in dir(it)
    print(res) #True

    8.调用迭代器

    next在调用迭代器中的数据时,是单向不可逆,一条路走到黑的过程

    当没有可迭代的数据后,抛出一个StopIteration的异常,并且停止迭代

    setvar = {"a","b","c","d"}
    it = iter(setvar) # 将可迭代对象setvar变成了迭代器
    res = next(it)
    print(res) # c
    res = next(it)
    print(res) # d
    res = next(it)
    print(res) # a
    res = next(it)
    print(res) # b
    res = next(it)
    print(res) # 当没有可迭代的数据后,抛出一个StopIteration的异常,并且停止迭代

    9.重置迭代器

    重置迭代器,只需要再次调用iter()方法即可

    it = iter(setvar) # 重置迭代器
    res = next(it)
    print(res)

    10.使用其他方式判断是否是可迭代对象/迭代器

    """Iterator 迭代器 Iterable 可迭代对象"""
    from collections import Iterator,Iterable
    it = iter(setvar)
    res = isinstance(it,Iterator)
    print(res)
    res = isinstance(it,Iterable)
    print(res)

    11.除了next(),也可以使用以下两种方式调用迭代器中的数据

    # 1. for 循环
    print("<=>")
    for i in it:
        print(i)
    
    # 2. for + next
    print("<=>")
    lst = [1,2,3,4,5,6,7,7,8,9,10]
    it = iter(lst)
    for i in range(10):
        res = next(it)
        print(res)
    
    print(next(it))
    print(next(it))

    高阶函数

    高阶函数的定义:能够把函数当成参数传递的就是高阶函数

    常用的四大高阶函数:map filter reduce sorted

    1.map

    map(func,Iterable)
      功能:处理数据
        把Iterable中的数据一个一个拿出来,扔到func函数中做处理
        把处理之后的结果放到迭代器当中,最后返回迭代器
      参数:
        func : 自定义函数 或 内置函数
        Iterable : 可迭代性数据(容器类型数据 range对象 迭代器)
      返回值:
        迭代器

    示例1:将["1","2","3","4"]转化成[1,2,3,4]

    常规写法:

    lst = ["1","2","3","4"]
    # 常规写法
    lst_new = []
    for i in lst:
        lst_new.append(int(i))
    print(lst_new)

    用map改造的写法:

    # map改造
    it = map(int,lst) # it是一个map对象
    print(list(it)) # [1,2,3,4]

    map(int,lst)的实现过程:

      首先把"1" 扔到int当中做处理,将强转后的结果扔到迭代器中
      然后把"2" 扔到int当中做处理,将强转后的结果扔到迭代器中
      然后把"3" 扔到int当中做处理,将强转后的结果扔到迭代器中
      然后把"4" 扔到int当中做处理,将强转后的结果扔到迭代器中
      最终返回迭代器

    获取迭代器中的数据的方法:1.next()  2.for循环遍历  3.for+next  4.list(it)强转

    示例2:[1,2,3,4] => [2,8,24,64]

    # map改造
    '''参数和返回值return一定要写'''
    def func(n):
        return n << n 
    lst = [1,2,3,4]    
    it = map(func,lst)
    print(list(it))
    
    # lambda + map 
    it = map(lambda n : n << n , lst)
    print(list(it))

    示例3:dic = {97:"a",98:"b",99:"c"} # ["a","b","c"] => ascii [97,98,99]

    # map改造
    def func(n):
        # 原字典
        dic = {97:"a",98:"b",99:"c"}
        # 新字典
        dic_new = {}
        # 遍历原字典
        for k,v in dic.items():
            # 更换键值对
            dic_new[v] = k
        print(dic_new) # {'a': 97, 'b': 98, 'c': 99}
        # 通过键来获取值
        return dic_new[n]
        
    lst = ["a","b","c"]
    it = map(func,lst)
    print(list(it))

    2.filter

    filter(func,iterable)
      功能: 过滤数据
        return True 当前这个数据保留
        return False 当前这个数据舍弃
      参数:
        func : 自定义函数
        iterable : 可迭代型数据(容器类型数据,range对象,迭代器)
      返回值:
        迭代器

    lst = [1,2,3,4,5,6,7,8,9,10]
    
    # 常规写法
    lst_new = []
    for i in lst:
        if i % 2 == 0:
            lst_new.append(i)
            
    print(lst_new)
    
    # filter改写
    def func(i):
        if i % 2 == 0:
            return True
        else:
            return False
    it = filter(func,lst)
    
    # filter + lambda 改写
    it = filter(lambda i : True if i % 2 == 0 else False , lst )
    print(list(it))

    3.reduce

    reduce(func,iterable)

      功能:计算数据
        先把iterable中的前两个值拿出来,扔到func当中做运算,
        把计算的结果和iterable中的第三个元素在扔到func当中做运算,
        再把结果算出来,和第四个元素做运算,以此类推
        直到所有结果运算完毕.返回该结果
      参数:
        func : 自定义函数
        iterable : 可迭代型数据(容器类型数据,range对象,迭代器)
      返回值:
        计算之后的结果

    示例1:lst = [5,4,8,8]  => 整型5488

    常规写法1:

    strvar = ""
    for i in lst:
        strvar += str(i)
    print(strvar , type(strvar))
    res = int(strvar)
    print(res , type(res))

    常规写法2:

    from collections import Iterator,Iterable
    lst = [5,4,8,8]
    it = iter(lst)
    print(isinstance(it , Iterator)) # True
    print(isinstance(it , Iterable)) # True
    
    num1 = next(it) # 5
    num2 = next(it) # 4
    num = num1 * 10 + num2 # 54
    
    for i in it:
        num = num * 10 + i # 54*10+8=548  548*10+8=5488
    print(num, type(num)) # 5488 <class 'int'>

    reduce改造:

    def func(x,y):
        return x*10 + y
    lst = [5,4,8,8]
    res = reduce(func,lst)
    print(res , type(res))

    reduce(func,lst)实现的过程:

    先拿出5和4两个元素,扔到func当中做运算,结果是54
    在拿54和8两个元素,扔到func当中做运算,结果548
    在拿548和8两个元素,扔到func当中做运算,结果5488
    返回最终的结果: 5488 程序结束

    reduce+lambda:

    res = reduce(lambda x,y:x*10+y,lst)
    print(res)

    示例2:"789"=>789 禁止使用int强制转换

    def func1(x,y):
        return x*10 + y
    def func2(n):
        dic = {"0":0,"1":1,"2":2,"3":3,"4":4,"5":5,"6":6,"7":7,"8":8,"9":9}
        return dic[n]
    it = map(func2,"789") # [7,8,9]
    res = reduce(func1,it)
    print(res,type(res))

    4.sorted

    sorted(iterable,key=函数,reverse=False)
      功能:排序
      参数:
        iterable:可迭代型数据(容器类型数据,range对象,迭代器)
        key :指定自定义函数或内置函数
        reverse :代表升序或者降序 , 默认是升序(从小到大排序) reverse=False
      返回值:
        排序后的结果

    # 1.默认是从小到大排序
    lst = [1,2,3,4,5,-90,-4,-1,100]
    res = sorted(lst)
    print(res)
    
    # 2.reverse 从大到小排序
    res = sorted(lst,reverse=True)
    print(res)
    
    # 3.指定函数进行排序
    # 按照绝对值排序 abs
    lst = [-10,-1,3,5]
    res = sorted(lst,key=abs)
    print(res)
    
    # 4.使用自定义函数进行排序
    lst = [19,21,38,43,55]
    def func(n):
        return n % 10
    lst = sorted(lst,key=func)
    print(lst)

    sort和sorted的区别:

    (1) sorted可以排序一切容器类型数据, sort只能排列表
    (2) sorted返回的是新列表,sort是基于原有的列表进行修改
    (3) 推荐使用sorted

  • 相关阅读:
    docker简单介绍----Dockerfile命令
    docker简单介绍----docker仓库的应用
    nginx实现https的配置文件
    docker简单介绍---网络端口管理
    mysql查看实时连接数
    linux 批量测试域名返回码脚本
    docker简单介绍----镜像和容器管理
    香冢
    GitHub 在使用命令行 git push 时报错:The requested URL returned error: 403
    守规矩应该被骂吗?
  • 原文地址:https://www.cnblogs.com/libolun/p/13358361.html
Copyright © 2011-2022 走看看