python-迭代器和生成器

迭代器及生成器

迭代器

内部含有_iter_方法的数据类型,就是可迭代的,
如:
print('_iter_' in dir('abc'))的执行结果如下:(请看是否有_iter_)

['__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']
#迭代器比可迭代的多一个_next_方法
#迭代器:包含_next_,_iter_方法的就是迭代器
#包含_next_方法的可迭代对象就是迭代器
l = [1,2,3,4,5]
lst_iter = l.__iter__()
print(dir(l))
print('__iter__' in dir(lst_iter))
print('__next__' in dir(lst_iter))
print(set(dir(lst_iter)) - set(dir(l)))
lst_iter.__next__()

执行结果如下:
['__add__', '__class__', '__contains__', '__delattr__', '__delitem__', '__dir__', '__doc__', '__eq__', '__format__', '__ge__', '__getattribute__', '__getitem__', '__gt__', '__hash__', '__iadd__', '__imul__', '__init__', '__init_subclass__', '__iter__', '__le__', '__len__', '__lt__', '__mul__', '__ne__', '__new__', '__reduce__', '__reduce_ex__', '__repr__', '__reversed__', '__rmul__', '__setattr__', '__setitem__', '__sizeof__', '__str__', '__subclasshook__', 'append', 'clear', 'copy', 'count', 'extend', 'index', 'insert', 'pop', 'remove', 'reverse', 'sort']
True
True
{'__length_hint__', '__next__', '__setstate__'}
# 例题:
# l = ['ha','hei','he']
# lst_iter = l.__iter__()
# print(lst_iter.__next__())
# print(lst_iter.__next__())
# print(lst_iter.__next__())
可迭代的 必须含有_iter_方法     #可迭代协议
迭代器比可迭代的多了一个_next_方法
迭代器:包含_next_,_iter_方法 #迭代器协议
包含_next_方法的可迭代对象就是迭代器
迭代器是可迭代的一部分
获得迭代器:可迭代的调用_iter_()
使用迭代器:迭代器_next_()
如何判断一个变量是不是迭代器或者可迭代的
方法一:
print('_iter_' in dir([1,2,3,4]))
print('_next_' in dir([1,2,3,4]))
方法二:
from collections import Iterable
from collections import Iterator
print(isinstance([1,2,3,4,5],Iterable))
str_iter = 'abc'.__iter__()
print(isinstance(str_iter,Iterator))
print(isinstance('abc',Iterator))
迭代器的特点:
惰性运算(要的时候才给,不要不给)
从前到后一次去取值,过程不可逆,不可重复
节省内存
用while循环模拟for循环的方法:
l = [1,2,3,4,5]
l_iter = l.__iter__()
while True:
    try:
        print(l_iter.__next__())
    except StopIteration:
        break
for 循环是让我们更简单的使用迭代器
用迭代器去值就不需要关心索引或者key的问题了
目前我们已知的可迭代的都是python提供给我们的(range(),f这里指的是文
件,enumerate()指的是枚举)

一个对象要想被for循环,这个对象如果有个__iter__方法,必须得返回一个迭代器.
# class Foo(object):
#     pass
#
# obj=Foo()
# for item in obj:
#     print(item)

# 要想被for循环,内部必须有iter方法


class Foo(object):
    def __iter__(self):
        return iter([1,2,3,4,5])        #列表是可迭代对象,iter(可迭代对象)就变成了迭代器

obj=Foo()
for item in obj:
    print(item)
对象想要被for循环,内部需要有一个__iter__方法,并返回一个迭代器




生成器
自己想写个可迭代的,---生成器
生成器的本质就是迭代器
因此生成器的所有好处都和迭代器一样
但是生成器是我们自己写的python代码
生成器的实现由两种方式:1.生成器函数,2.生成器表达式
def g_func():
    yield 1

g = g_func()
print(g)
# generator  生成器  本质还是迭代器
print(g.__next__())
生成器函数和普通函数之间的区别
生成器函数中含有yield关键字
生成器函数调用的时候不会立即执行,而是返回一个生成器
def g_func():
    for i in range(2000):
        yield i

g = g_func()
print(g.__next__())
print(g.__next__())
print(g.__next__())

例题

def cloth():
    for i in range(1000):
        yield '衣服%s'%i

g = cloth()
for i in range(50):
    print(g.__next__())
原文地址:https://www.cnblogs.com/dwenwen/p/7780272.html