zoukankan      html  css  js  c++  java
  • python 迭代器和生成器

    for循环的本质:循环所有对象,全都是使用迭代器协议。

    第一部分

    关于为什么要用迭代器:   

    优点:

    1:迭代器提供了一种不依赖于索引的取值方式,这样就可以遍历那些没有索引的可迭代对象了(字典,集合,文件)

    2:迭代器与列表比较,迭代器是惰性计算的,更节省内存

    缺点:

    1:无法获取迭代器的长度,使用不如列表索引取值灵活
    2:一次性的,只能往后取值,不能倒着取值
    用以下例子示例:

    用索引取字典的内容:
    d=[1,2,3]
    i=0
    while i < len(d):
        print(d[i])
        i+=1
    

     其执行结果是:

    1
    2
    3
    

     用索引取列表的内容:

    d=[1,2,3]
    for i in range(len(d)):
        print(d[i])
    

      其执行结果是:

    1
    2
    3
    

      用迭代器的方法分别取字典的值:

    #用迭代器的方式取字典的内容()不依靠索引
    d={"a":1,"b":2,"c":3}
    i=d.__iter__()#生成迭代器
    #print(i.__next__())#打印内容
    while True:
        try:
            print(i.__next__())#打印内容
        except StopIteration:
            break
    

      其执行结果是:

    a
    b
    c
    

      用迭代器的方法取列表里的元素:

    #用迭代器的方式取列表的内容()不依靠索引
    d=[1,2,3,4,5]
    i=d.__iter__()#生成迭代器
    # print(i.__next__())#打印内容
    while True:
        try:
            print(i.__next__())
        except StopIteration:
            break
    

      其执行结果是:

    1
    2
    3
    4
    5
    

     总结:

    (1)、可迭代的:只要对象本身有__iter__方法,那它就是可迭代的

            d={'a':1,'b':2,'c':3}

            d.__iter__ #iter(d)(表示d是可迭代的)

    (2)、执行对象下的__iter__方法,得到的结果就是迭代器

             i=d.__iter__()(i即是迭代器)

    (3)3、i.__next__()(即表示的就是执行从字典d里取值)

         print(i.__next__())
    print(i.__next__())
    print(i.__next__())



    关于迭代器的使用,用以下举例:
    用字典示例while循环(由于print(i.__next__())每次输出只能是一个值,但是如果字典里的元素一共有3个,打印4个print(i.__next__())就会报错)
    #由于print(i.__next__())每次输出只能是一个值,但是如果字典里的元素一共有3个,打印4个print(i.__next__())就会报错,故而使用下列方法可以全部打印且不报错
    d={'a':1,'b':2,'c':3}
    i=iter(d)#即i=d._iter_()
    while True:
        try:
            print(next(i))#即print(i.__next__())
        except StopIteration:
            break
    

     执行结果是:

    a
    b
    c
    

     用列表示例while循环:

    l=['a','b','c','d','e']
    i=l.__iter__()
    while True:
        try:
            print(next(i))#即print(i.__next__())
        except StopIteration:
            break
    

     执行结果是:

    a
    b
    c
    d
    e
    

      

    用字典示例:(for循环)
    d={'a':1,'b':2,'c':3}
    d.__iter__#代表d是可迭代的
    for k in d: #d.__iter__()#取字典里key的值
        print(k)
    

     其执行结果是:

    a
    b
    c
    

      

    用集合示例(for循环)
    s={1,2,3,4}
    s.__iter__()#s是可迭代的
    for i in s:
        print(i)
    

     执行结果是:

    1
    2
    3
    4
    

     

    用文件示例,往文件里写入内容
    with open('a.txt','r') as f:
        f.__iter__()#f是可迭代的
        for line in f:#相当于执行的是print(f.__next__)并且不会报错
            print(line)
    

     执行结果是:

    aaaaaa
    
    bbb
    
    cccc
    
    eee
    
    ffffff
    

      

    关于迭代器,补充的有:

    用列表示例,如果列表里有3个元素,故而打印4个print(next(i))会报错
    l=[1,2,3]
    print(len(l))
    i=iter(l)#l是可迭代的
    print(next(i))
    print(next(i))
    print(next(i))
    print(next(i))
    

      执行结果是:

    3
    1
    2
    3
    Traceback (most recent call last):
      File "C:/Users/Administrator/PycharmProjects/py_fullstack_s4/day23/迭代器.py", line 109, in <module>
        print(next(i))
    StopIteration
    

     报错原因是: 因为迭代器是一次性的,只能往后取值,不能倒着取值



    用列表示例,如果列表里有3个元素,print(next(i))打印3次列表里的元素,则for循环无元素可打印
    l=[1,2,3]
    print(len(l))#输出列表l的长度
    i=iter(l)#l是可迭代的
    print(next(i))
    print(next(i))
    print(next(i))
    for x in i:
        print(x)
    

     执行结果是:

    3
    1
    2
    3
    

      结论:for循环没有进行



    用列表示例,如果列表里有3个元素,print(next(i))打印1次列表里的元素,则for循环可打印剩下的2个元素
    l=[1,2,3]
    print(len(l))#输出列表l的长度
    i=iter(l)#l是可迭代的
    print(next(i))
    for x in i:
        print(x)
    

     执行结果是:

    3#由print(len(l))打印的结果
    1 #由print(next(i)打印的结果
    2 #由for循环打印的结果
    3#由for循环打印的结果

      

     第二部分

    查看可迭代对象与迭代器对象
    通过from collections import Iterable,Iterator来查看
    分别查看字符串、列表、元组、字典、集合、文件是否是可迭代对象与迭代器对象
    s='hello'
    l=[1,2,3]
    t=(1,2,3)
    d={'a':1}
    set1={1,2,3,4}
    f=open('a.txt')
    示例:查看是否是可迭代对象
    s='hello'
    l=[1,2,3]
    t=(1,2,3)
    d={'a':1}
    set1={1,2,3,4}
    f=open('a.txt')
    
    # 判断是否是可迭代对象,返回Ture是可迭代的
    s.__iter__()
    l.__iter__()
    t.__iter__()
    d.__iter__()
    set1.__iter__()
    f.__iter__()
    print(isinstance(s,Iterable))
    print(isinstance(l,Iterable))
    print(isinstance(t,Iterable))
    print(isinstance(d,Iterable))
    print(isinstance(set1,Iterable))
    print(isinstance(f,Iterable))
    # 发现都是可迭代的
    

     其执行结果是:

    True
    True
    True
    True
    True
    True
    

     示例:判断是否是迭代器

    # 判断查看是否是迭代器,返回Ture是迭代器
    s='hello'
    l=[1,2,3]
    t=(1,2,3)
    d={'a':1}
    set1={1,2,3,4}
    f=open('a.txt')
    
    print(isinstance(s,Iterator))
    print(isinstance(l,Iterator))
    print(isinstance(t,Iterator))
    print(isinstance(d,Iterator))
    print(isinstance(set1,Iterator))
    print(isinstance(f,Iterator))
    

     执行结果是:

    False
    False
    False
    False
    False
    True
    

     返回结果是只有文件是迭代器

     

    第三部分
    生成器就是一个函数,这个函数内包含有yield这个关键字


    关于生成器yield的返回值和函数中return的返回值有何区别:
    区别是:return只能返回一次函数就彻底结束了,而yield能返回多次值
    yield到底有何作用:
    1.yield把函数变成生成器-->迭代器
    2.用return返回值能返回一次,而yield返回多次
    3.函数在暂停以及继续下一次运行时的状态是由yield保存

    示例说明:
    def countdown(n):
        print('start coutdown')
        while n > 0:
            yield n #有yield将函数变成了生成器
            n-=1
    g=countdown(5)
    print(isinstance(g,Iterator))#判断g是一个迭代器
    print(g)#返回内存地址
    print(next(g))
    print(next(g))
    print(next(g))
    print(next(g))
    print(next(g))
    

     执行结果:

    True
    <generator object countdown at 0x0000000001E20620>
    start coutdown
    5
    4
    3
    2
    1
    

      

     

  • 相关阅读:
    快速创建一个 Servlet 项目(1)
    快速创建一个 Servlet 项目(2)
    多级派生情况下派生类的构造函数
    最近看了点C++,分享一下我的进度吧!
    进程同步&进程间通信
    multiprocess模块
    进程
    网络编程之socket
    网络通信原理
    网络通信的流程 | 初始socket
  • 原文地址:https://www.cnblogs.com/xuyuanyuan123/p/6694737.html
Copyright © 2011-2022 走看看