zoukankan      html  css  js  c++  java
  • 迭代器,生成器,列表推导式,生成器表达式

    迭代器:

    可迭代对象:内部含有__inter__的

    可迭代对象不能取值,因为内部没有__next__()方法

    可迭代对象------>迭代器:

      boj.__iter__()或者inter(obj)

    实现的原理类似于往弹匣里面装子弹,然后一个一个往外发射

    通过__iter__()来获取到迭代器

    1 stes = {1, 2, 3, 4, 5, 67, 7}
    2 print(stes.__dir__())
    3 s = stes.__iter__()
    4 print(s)
    迭代器

    打印结果

    1 ['__repr__', '__hash__', '__getattribute__', '__lt__', '__le__', '__eq__', '__ne__', '__gt__', '__ge__', '__iter__', '__init__', '__sub__', '__rsub__', '__and__', '__rand__', '__xor__', '__rxor__', '__or__', '__ror__', '__isub__', '__iand__', '__ixor__', '__ior__', '__len__', '__contains__', '__new__', 'add', 'clear', 'copy', 'discard', 'difference', 'difference_update', 'intersection', 'intersection_update', 'isdisjoint', 'issubset', 'issuperset', 'pop', '__reduce__', 'remove', '__sizeof__', 'symmetric_difference', 'symmetric_difference_update', 'union', 'update', '__doc__', '__str__', '__setattr__', '__delattr__', '__reduce_ex__', '__subclasshook__', '__init_subclass__', '__format__', '__dir__', '__class__']
    2 <set_iterator object at 0x0000000001EF1480>
    打印结果

    通过__next__()来拿到元素,一次只能拿一个,如果最后一个元素之后继续使用__next__(),会报错:StopIteration

     1 stes = {1, 2, 3, 4, 5, 67, 7}
     2 s = stes.__iter__()
     3 print(s.__next__())
     4 print(s.__next__())
     5 print(s.__next__())
     6 print(s.__next__())
     7 print(s.__next__())
     8 print(s.__next__())
     9 print(s.__next__())
    10 print(s.__next__())
    __next__()

    打印结果为:

     1 1
     2 2
     3 3
     4 4
     5 5
     6 67
     7 7
     8 Traceback (most recent call last):
     9   File "C:/Python/Module/regex_test.py", line 53, in <module>
    10     print(s.__next__())
    11 StopIteration
    打印结果

    判断是否为迭代器:

      1.通过__iter__(),__next__()是否在obj.__dir__()

    1 with open('01','w', encoding='utf-8') as f:
    2     print('__iter__' in dir(f))
    3     print('__next__' in dir(f))
    4 """
    5 打印结果:
    6 True
    7 True
    8 说明文件句柄本身是一个迭代器
    9 """
    dir方法

      2.通过collections模块中的Iterable来判断

     1 from collections import Iterable
     2 from collections import Iterator
     3 
     4 l = [1,2,3,4]
     5 print(isinstance(l, Iterable))    # 判断是否为可迭代对象
     6 print(isinstance(l, list))
     7 
     8 
     9 """
    10 打印结果:
    11 True
    12 True
    13 """
    14 
    15 l = [1,2,3,4]
    16 print(isinstance(l, Iterable))
    17 print(isinstance(l, Iterator))
    18 print(isinstance(l, list))
    19 
    20 """
    21 打印结果:
    22 True
    23 False
    24 True
    25 """
    Iterable

    生成器:

    生成器实质就是迭代器,在python中有三种方式来获取生成器:

    1. 通过生成器函数
    2. 通过各种推导式来实现来生成器
    3. 通过数据的转换也可以获取生成器

     生成器是我们自己用Python代码写的迭代器:

     1 def gener():
     2     print(111)
     3     yield 222
     4     print(333)
     5     yield 444
     6     print(555)
     7     yield 666
     8     print(777)
     9     yield 888
    10 
    11 
    12 gen = gener()
    13 print(gen)
    14 
    15 # 打印结果为:<generator object gener at 0x0000000001E74D00>
    生成器

    生成器函数和普通的函数的区别就是把return换成了yield

     yield 和return区别

      1. 如果函数中包含了yield, 这个函数是一个生成器函数. 执行函数的时候是: 生成器

      2. 生成器执行__next__(). 执行到下一个yield

      3. yield的作用和return基本相同. 但是,只负责返回. 不会结束函数

      4. return,结束函数.

    通过obj__next__()方法取值:

     1 def gener():
     2     print(111)
     3     yield 222
     4     print(333)
     5     yield 444
     6     print(555)
     7     yield 666
     8     print(777)
     9     yield 888
    10 
    11 
    12 gen = gener()
    13 print(gen)
    14 ret = gen.__next__()    # 这里的ret相当于执行函数,直行道yield是返回yield的返回值
    15 print(ret)
    16 ret1 = gen.__next__()    
    17 print(ret1)
    18 ret2 = gen.__next__()    
    19 print(ret2)
    20 ret3 = gen.__next__()    
    21 print(ret3)
    22 
    23 """
    24 打印结果:
    25 <generator object gener at 0x0000000000814D00>
    26 111
    27 222
    28 333
    29 444
    30 555
    31 666
    32 777
    33 888
    34 """
    生成器取值

    生成器还可以通过send()方法进行取值个传值,不过使用send方法时要注意的是:

      1.第一个yield必须通过__next__()方法取得

      2.最后一个yield不能通过send()方法传值.

     1 def gener():
     2     print(111)
     3     a = yield 222
     4     print(a)
     5     print(333)
     6     b = yield 444
     7     print(b)
     8     print(555)
     9     c = yield 666
    10     print(c)
    11     print(777)
    12     yield 888
    13 
    14 
    15 gen = gener()
    16 print(gen)
    17 ret = gen.__next__()    
    18 print(ret)
    19 ret1 = gen.send('<<>>')    
    20 print(ret1)
    21 ret2 = gen.send('<<>>')    
    22 print(ret2)
    23 ret3 = gen.send('<<>>')    
    24 print(ret3)
    25 
    26 """
    27 打印结果:
    28 <generator object gener at 0x0000000001DD4D00>
    29 111
    30 222
    31 <<>>
    32 333
    33 444
    34 <<>>
    35 555
    36 666
    37 <<>>
    38 777
    39 888
    40 """
    send()方法

    使用send()方法时要注意的是要传参,不然会报错

    send和__next__() 区别:

      send可以给上一个yield 的位置传递值 , 第一个必须用__next__()

      __next__() 不能传值

    列表推导式:

    需要一个列表,里面包含1到13的数字,第一反应是:

    1 l = []
    2 
    3 for i in range(1, 14):
    4     l.append(i)
    5 print(l)
    6 # 打印结果:[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]
    生成一个列表

     我们来看这样一段代码:

    1 l = [ i for i in range(1,14)]
    2 print(l)
    3 
    4 #打印结果:[1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13]
    列表推导式

    有这样一个需求,通过列表推导式来筛选憨厚两个e的名字:

    1 names = [['Tom', 'Billy', 'Jefferson', 'Andrew', 'Wesley', 'Steven', 'Joe'],
    2          ['Alice', 'Jill', 'Ana', 'Wendy', 'Jennifer', 'Sherry', 'Eva']]
    3 name2 = [name for i in names for name in i if name.count('e') == 2]
    4 print(name2)
    5 
    6 # 打印结果:['Jefferson', 'Wesley', 'Steven', 'Jennifer']
    筛选模式

    l = [变量(加工后的变量) for 变量 in iterable] 循环模式

    l = [变量(加工后的变量) for 变量 in iterable if 条件] 筛选模式

    类似于真样的式子被成为列表推导式.

    优点:

    1,节省代码,一行搞定.

    2,看着高大上.

    缺点:

    不好排错.

    整体:

    凡是用列表推导式构造的列表对象,用其他方式都可构建.,非常复杂的列表,列表推导式是构建不出的,

    列表推导式比较有魔性.

    生成器表达式:

    生成器表达式和列表推导式基本一样,唯一的区别就是把列表推推导式的方括号变成圆括号:

    1 l = ( i for i in range(1,14))
    2 print(l)
    3 
    4 #打印结果:<generator object <genexpr> at 0x0000000001F24D00>
    生成器表达式

    同样的也有两种模式:

    循环模式和筛选模式

  • 相关阅读:
    20175311 2018-2019-2 《Java程序设计》第7周学习总结
    20175311胡济栋 2018-2019-2《Java程序设计》结对编程项目-四则运算 第一周 阶段性总结
    20175314 《信息安全系统设计基础》课程总结
    USCOSII
    改进ls的实现
    cat userlist
    实现ls
    stat命令的实现-mysate
    实现mypwd
    2019-2020-1 20175314_20175316 实验五 通讯协议设计
  • 原文地址:https://www.cnblogs.com/linga/p/9309899.html
Copyright © 2011-2022 走看看