zoukankan      html  css  js  c++  java
  • 迭代器、可迭代对象、迭代器对象、生成器、生成器表达式和相关的面试题

    迭代器:

    迭代的工具。迭代是更新换代,如你爷爷生了你爹,你爹生了你,迭代也可以说成是重复,并且但每一次的重复都是基于上一次的结果来的。如计算机中的迭代开发,就是基于软件的上一个版本更新。以下代码就不是迭代,它只是单纯的重复

    可迭代对象

    python中一切皆对象,对于这一切的对象中,但凡有__iter__方法的对象,都是可迭代对象。
    
    可迭代的对象:Python内置str、list、tuple、dict、set、file都是可迭代对象。

    迭代器对象

    只有字符串和列表都是依赖索引取值的,而其他的可迭代对象都是无法依赖索引取值的。因此我们得找到一个方法能让其他的可迭代对象不依赖索引取值。
    
    在找到该方法前,首先我们给出迭代器对象的概念:可迭代的对象执行__iter__方法得到的返回值。并且可迭代对象会有一个__next__方法。
    
    一定次数后要是__next__() 调用超出上限会导致无值可取 报错StopIteration
    
    但是在我们可以使用while循环精简下。其中使用的try...except...为异常处理模块

    总结

    迭代器对象:执行可迭代对象的__iter__方法,拿到的返回值就是迭代器对象。
    
    特点:
    
    内置__next__方法,执行该方法会拿到迭代器对象中的一个值
    内置有__iter__方法,执行该方法会拿到迭代器本身
    文件本身就是迭代器对象。
    缺点:
    
    取值麻烦,只能一个一个取,并且只能往后取,值取了就没了
    无法使用len()方法获取长度

    for循环原理

    for循环称为迭代器循环,in后必须是可迭代的对象。
    将in后面的对象调用__iter__转换成迭代器对象
    调用__next__迭代取值
    内部有异常捕获StopIteration,当__next__报这个错 自动结束循环

    迭代器对象无论执行多少次__iter__方法得到的还是迭代器对象本身(******)

    迭代器取值的特点
    1.只能往后依次取 不能后退

    特别注意类型:文件类型

    文件类型本身就是一个迭代器对象
    
    问:__iter__方法就是用来帮我们生成迭代器对象
    而文件对象本身就是迭代器对象,为什么还内置有__iter__方法???
    解答:for 循环 时候必须要有__iter__方法 这是必须步骤 ,所以~~~~
    # f = open('xxx.txt','r',encoding='utf-8')
    # iter_f = f.__iter__()
    # print(iter_f.__next__())
    # print(iter_f.__next__())
    # print(iter_f.__next__())
    # print(iter_f.__next__())
    # print(iter_f.__next__())

    生成器

    yield
    1.帮你提供了一种自定义生成器方式
    2.会帮你将函数的运行状态暂停住
    3.可以返回值

    与return之间异同点
    相同点:都可以返回值,并且都可以返回多个
    不同点:
    yield可以返回多次值,而return只能返回一次函数立即结束
    yield还可以接受外部传入的值

    用户自定义的迭代器,本质就是迭代器

    生成器的自主yield 传值

    # def func():
    #     print('first')
    #     yield  666  # 函数内如果有yield关键字,那么加括号执行函数的时候并不会触发函数体代码的运行
    #     print('second')
    #     yield  777
    #     print('third')
    #     yield  888
    #     print('forth')
    #     yield
    #     yield
    # # yield后面跟的值就是调用迭代器__next__方法你能得到的值
    # # yield既可以返回一个值也可以返回多个值 并且多个值也是按照元组的形式返回
    # g = func()  # 生成器初始化:将函数变成迭代器
    # print(g)
    # print(g.__next__())
    # print(g.__next__())
    # print(g.__next__())
    # print(g.__next__())
    # print(g.__next__())

    迭代yield生成后取数例子

    def my_range(start,end,step=1):
        while start < end:
            yield start
            start += step
    
    
    for j in my_range(1,100,2):
        print(j)

     yield支持外界为其传参

    def dog(name):
    print('%s 准备开吃'%name)
    while True:
    food = yield
    print('%s 吃了 %s'%(name,food))
    # def index():
    # pass

    # 当函数内有yield关键字的时候,调用该函数不会执行函数体代码
    # 而是将函数变成生成器
    # g = dog('egon')
    # g.__next__() # 必须先将代码运行至yield 才能够为其传值
    # g.send('狗不理包子') # 给yield左边的变量传参 触发了__next__方法
    # g.send('饺子')

     生成式表达式

     ()    

    # 生成器不会主动执行任何一行代码
    # 必须通过__next__触发代码的运行

    列子如

    # res = (i for i in range(1,100000000) if i != 4)  # 生成器表达式
    # print(res)
    # f = open('xxx.txt','r',encoding='utf-8')
    # data = f.read()
    # print(len(data))
    # f.close()
    
    # with open('xxx.txt','r',encoding='utf-8') as f:
    #     # n = 0
    #     # for line in f:
    #     #     n += len(line)
    #     # print(n)
    #     g = (len(line) for line in f)
    #     # print(g.__next__())
    #     # print(g.__next__())
    #     # print(g.__next__())
    #     # print(g.__next__())
    #     print(sum(g))

    列子

    生成器和迭代器的结合面试题

     还有要注意  list()  list分为3步骤  转化为 迭代器对象 然后迭代 然后添加入列表   他会执行__next__ 会把老母鸡的蛋给偷走!!!!!!!!!!!!!!!!!!!!!!!!!

  • 相关阅读:
    利用存储过程生成随机数,并用其它存储过程调用此过程
    dataGridView中的数据操作
    listView绑定数据
    我的简易 数据存取器 的封装
    dataGridView 控件的简单绑定
    文件写入写出的封装
    Button1.Attributes.Add()方法小结
    自定义分页栏
    安迪的找工作日志——9.12笔试(优酷土豆)问题及解答
    安迪的找工作日志——9.13在教四四楼墙上看到的
  • 原文地址:https://www.cnblogs.com/jinpan/p/11192284.html
Copyright © 2011-2022 走看看