迭代器和生成器

一.迭代器

1.1可迭代对象

1.1.1可迭代对象定义

  • 在python中,但凡内部含有iter方法的对象,都是可迭代对象

1.1.2查看对象内部方法

  • 该对象内部含有什么方法除了看源码还有什么其他的解决方式么?当然有了, 可以通过dir() 去判断一个对象具有什么方法

    s1 = '张三'
    print(dir(s1))
    
    #结果
    ['__add__', '__class__', '__contains__', '__delattr__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__getnewargs__', '__gt__', '__hash__', '__init__', '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__mod__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__rmod__', '__rmul__', '__setattr__', '__sizeof__', '__str__', '__subclasshook__', 'capitalize', 'casefold', 'center', 'count', 'encode', 'endswith', 'expandtabs', 'find', 'format', 'format_map', 'index', 'isalnum', 'isalpha', 'isdecimal', 'isdigit', 'isidentifier', 'islower', 'isnumeric', 'isprintable', 'isspace', 'istitle', 'isupper', 'join', 'ljust', 'lower', 'lstrip', 'maketrans', 'partition', 'replace', 'rfind', 'rindex', 'rjust', 'rpartition', 'rsplit', 'rstrip', 'split', 'splitlines', 'startswith', 'strip', 'swapcase', 'title', 'translate', 'upper', 'zfill']

1.2迭代器

1.2.1迭代器的定义

  • 我们简单来说:在python中,内部含有'Iter'方法并且含有'next'方法的对象就是迭代器。

1.2.2如何判断该对象是否是迭代器

  • 示例:请判断这些对象:str list tuple dict set range 文件句柄 哪个是迭代器,哪个是可迭代对象:

    n1 = '张三'
    n2 = [1, 2, 3]
    n3 = (1, 2, 3)
    n4 = {'name': '李四','age': 18}
    n5 = {1, 2, 3}
    f = open('file',encoding='utf-8', mode='w')
    print('__iter__' in dir(n1))  # True
    print('__iter__' in dir(n2))  # True
    print('__iter__' in dir(n3))  # True
    print('__iter__' in dir(n4))  # True
    print('__iter__' in dir(n5))  # True
    print('__iter__' in dir(f))  # True
    # hsagn
    print('__next__' in dir(n1))  # False
    print('__next__' in dir(n2))  # False
    print('__next__' in dir(n3))  # False
    print('__next__' in dir(n4))  # False
    print('__next__' in dir(n5))  # False
    print('__next__' in dir(f))  # True
    f.close()

    所以只有文件句柄是迭代器,剩下的那些数据类型都是可迭代对象。

1.2.3可迭代对象如何转化成迭代器

a1 = [1, 2, 3, 4, 5, 6]
obj = a1.__iter__()
print(obj)    #<list_iterator object at 0x00000000025A8A20>
obj2 = iter(a1)
print(obj2)   #<list_iterator object at 0x0000000002528D30>

1.2.4迭代器取值

a1 = [1, 2, 3]
obj = a1.__iter__()
​
ret = obj.__next__()
print(ret)       # 1
ret = obj.__next__()
print(ret)       # 2
ret = obj.__next__()
print(ret)       # 3
ret = obj.__next__()
print(ret)      # StopIteration

# 迭代器利用next取值:一个next取对应的一个值,如果迭代器里面的值取完了,还要next,
# 那么就报StopIteration的错误。

二.生成器

2.1生成器函数

  • 和普通函数没有区别,里面有yield的函数就是生成器函数

  • 生成器函数在执行的时候,默认不会执行函数体,返回生成器

  • 通过生成器的next()分段执行这个函数

  • send()给上一个yield传值,不能在开头(没有上一个yield),最后一个yield也不能用send()

    def func():
        print("abc")
        yield 1
        print("def")
        yield 2
        
    n1 = func()
    print(n1.__next__())
    print(n1.__next__())

    return 和yield都可以返回数据,n1 = func()不会执行函数,拿到的是生成器,执行生成器需要用next()

    函数中如果有yield,这个函数就是生成器函数,生成器函数获取的是生成器

    yield:相当于return,可以返回数据,但是yield不会彻底中断函数,而是分段执行函数

    def func():
        yield 1
        yield 2
        yield 3print(list(func()))   #内部有__next__()
    for i in func():#for的内部一定有__next__()
        print(i)

2.2生成器

  • 生成器的本质就是迭代器

  • 生成器的特点和迭代器一样,取值方式和迭代器一样(next())

 

posted @ 2019-10-19 15:59  Primrose  阅读(122)  评论(0编辑  收藏  举报