• day13-迭代器、三元表达式、列表推导式、字典生成式、生成器与递归


    迭代器

    迭代器即迭代的工具,迭代是一个重复的过程,每次重复即是一次迭代,并且每次迭代的结果都是下一次迭代的初始值

    可迭代对象

    只要拥有__iter__()方法的对象就是可迭代对象,如下:

    print('name'.__iter__())
    print(['read', 'run',[1,2,3,4]].__iter__())
    print(('name',18,('age',14,'weight')).__iter__())
    print({'name': 'nick', 'age': 18}.__iter__())
    print({1,2,3,4,5}.__iter__())
    print(open('a.txt').__iter__())
    print(18.__iter__())      #  提示nvalid syntax
    def f1():
        pass
    print(f1.__iter())        # 报错提示函数没有iter方法“AttributeError: 'function' object has no attribute '__iter'”
    
    <str_iterator object at 0x0000011DA1C6AF28>
    <list_iterator object at 0x0000011DA1C6AF98>
    <tuple_iterator object at 0x0000011DA1C0FB00>
    <dict_keyiterator object at 0x0000011DA1A706D8>
    <set_iterator object at 0x0000011DA1C68630>
    <_io.TextIOWrapper name='a.txt' mode='r' encoding='cp936'>
    

    可见:字符串/列表/元组/字典/集合/文件都是可迭代对象

    迭代器对象

    拥有__iter__()和__next__方法的才是迭代器对象。其中,__next__其实是在遍历可迭代对象的元素,一旦遍历完报错,如

    lis_iter = [1,2,3].__iter__()
    print(lis_iter.__next__())        # 遍历列表中的第一个元素 1
    print(lis_iter.__next__())        # 遍历列表中的第一个元素 2
    print(lis_iter.__next__())        # 遍历列表中的第一个元素 3
    print(lis_iter.__next__())        # 遍历完后报错
    
    1
    2
    3
    
    ---------------------------------------------------------------------------
    
    StopIteration                             Traceback (most recent call last)
    
    <ipython-input-23-2aa8b474bc11> in <module>
          3 print(lis_iter.__next__())        # 遍历列表中的第一个元素 2
          4 print(lis_iter.__next__())        # 遍历列表中的第一个元素 3
    ----> 5 print(lis_iter.__next__())
    
    StopIteration: 
    
    print([1,2,3].__iter__().__iter__())        # 迭代器对象使用__iter__方法后是迭代器对象本身
    
    <list_iterator object at 0x0000011DA1C6A080>
    
    print(open('a.txt').__next__())
    print(open('a.txt').__iter__())
    # 文件即是可迭代对象也是迭代器对象
    
    
    Hello world
    <_io.TextIOWrapper name='a.txt' mode='r' encoding='cp936'>
    
    

    优点:节省内存空间

    缺点:取值麻烦,只能一个一个取,并且只能往后去,值取了就没了;无法使用len()方法获取长度

    注意:迭代器对象一定是可迭代对象,但是可迭代对象不一定是迭代器对象

    for循环原理

    只有字符串、列表和元组依赖索引取值色,而其他可迭代对象都是无法依赖索引取值的,有了迭代器,我们就可以不依赖索引迭代取值了

    lis = ['run','read']
    lis_iter = lis.__iter__()
    while True:
        try:
            print(lis_iter.__next__())
        except:
            break
    
    
    run
    read
    
    
    # 基于for循环,我们可以完全不再依赖索引取值
    lis = ['run','read']
    for i in lis:
        print(i,end=',')
    
    
    run,read,
    
    

    for循环的工作原理

    1. 执行in后对象的lis.iter()方法,得到一个迭代器对象lis_iter
    2. 执行lis_iter.next(),将得到的值赋给i,然后执行循环体代码
    3. 重复过程2,直到捕捉到异常结束循环

    三元表达式(三目表达式)

    # 示例:返回x和y的最大值
    x = 20
    y = 10
    if x > y:
        print(x)
    else:
        print(y)
    
        
    # 用三元表达式写
    x, y = 20, 10
    max = x if x > y else y        
    print(max)
    
    

    列表推导式

    # 示例:求0-9数的平方
    lis = []
    for i in range(10):
        lis.append(i*2)
    print(lis)
    
    
    # 用列表推导式写
    lis = [i*2 for i in range(10)]
    print(lis)
    
    

    字典生成式

    dic = {i:i**2 for i in range(5)}
    print(dic)
    
    
    {0: 0, 1: 1, 2: 4, 3: 9, 4: 16}
    
    

    zip()方法

    # 拉链函数
    res = zip('abcd',[1,2,3,4])
    print(res)
    dic = dict()
    for k,v in res:
        dic[k] = v
    print(dic)
    
    
    <zip object at 0x0000011DA1C6E788>
    {'a': 1, 'b': 2, 'c': 3, 'd': 4}
    
    

    zip()函数用于将可迭代的对象作为参数,将对象中对应的元素打包成一个个元组

    print({k:v for k,v in zip('abcd',[1,2,3,4])})
    
    
    {'a': 1, 'b': 2, 'c': 3, 'd': 4}
    
    

    生成器

    只要函数内部包含有yield关键字,那么函数名()得到的结果就是生成器,接收值但是不会执行函数内部的代码

    def func():
        yield 
        print('from 1')
        yield 2
        print('from 2')
        yield 'a',[1,2,3]
    g = func()
    print(g)
    print(g.__next__())
    print(g.__next__())
    print(g.__next__())
    
    
    <generator object func at 0x0000011DA1C1F6D0>
    None
    from 1
    2
    from 2
    ('a', [1, 2, 3])
    
    

    生成器本质上就是自定义的迭代器,因此可以通过.__next__()方法接收yield返回的值。

    yield可以暂停住函数,并且提供当前的返回值

    yield默认返回None;有一个返回值时返回一个值;有多个返回值时,以元组的形式接收返回值。但是yield不会结束函数,然后继续下一行代码,直到return。

    生成器表达式

    tup = (i for i in range(10))
    print(tup)
    for i in tup:
        print(i,end=',')
    
    
    <generator object <genexpr> at 0x0000011DA1C1F728>
    0,1,2,3,4,5,6,7,8,9,
    
    

    递归

    函数递归:它是一种特殊的函数嵌套,但是它在调用中又直接或间接地调用了它自身

    def f():
        print('from f')
        f()
    f()        # 进入了死循环
    
    

    如果递归函数不断地调用函数自身,那么这个递归函数就会进入一个死循环,所以必须给递归函数一个明确的结束条件

    递归的两个阶段

    1. 递推:一层一层递归调用下去,进入下一层递归的问题规模都将会减小
    2. 回溯:递归必须要有一个明确的结束条件,在满足该条件开始一层一层回溯

    递归的精髓在于通过不断地重复逼近一个最终的结果

    def guess_age(age,count):
        age -= 2
        count -= 1
        if count == 1:
            print(age)
            return
        guess_age(age,count)
    
    guess_age(38,5)
    
    
    30
    
    
  • 相关阅读:
    容器镜像加速器配置(Windows)
    容器镜像加速器配置(CentOS)
    kubernetes部署基于kubeadmin部署单机版本
    k8s之calico部署
    PHP连接SQLSERVER及中文乱码问题
    通过css grid实现圣杯布局
    sequelize操作数据库
    vue 导出excel中的多个sheet
    caffe python 接口api
    linux tmux 详细教程,Linux中Tmux的安装和基本用法
  • 原文地址:https://www.cnblogs.com/863652104kai/p/10970109.html
Copyright © 2020-2023  润新知