python基础9 (迭代器、生成器)

1、可迭代对象

迭代:将某个数据集内的数据“一个挨着一个的取出来”
可迭代协议:可以被迭代要满足的要求,即内部含有__iter__()方法
可迭代的类型:字符串、列表、元组、字典、集合
特点:惰性运算
#我们可以用dir()来查看是否还有__iter__()方法 have_iter = '__iter__' in dir([1,2]) #如果有,则have_iter = True

 

2、迭代器、__next__()

当我们调用可迭代对象的__iter__方法的时候,会返回一个例如list_iterator的类型,就是一个迭代器

迭代器协议:必须拥有__iter__方法和__next__方法

l = [1,2,3,4]
l_iter = l.__iter()__    #获得了迭代器
ret1 = l_iter.__next__()    #获得第一个元素
ret2 = l_iter.__next__()    #获得第二个元素

for循环就是这样进行迭代的

3、生成器、yield

Python中提供的生成器:
1.生成器函数:常规函数定义,但是,使用yield语句而不是return语句返回结果。

2.生成器表达式:类似于列表推导,但是,生成器返回按需产生结果的一个对象,而不是一次构建一个结果列表

#yield
yield语句一次返回一个结果,在每个结果中间,挂起函数的状态,以便下次重它离开的地方继续执行。通过调用__next__()和send()可以使生成器继续执行到下一个yield,不同的是send会传一个值给上一个yield

4、生成器函数

#例子:生成500万个hsr
def generate_hsr():
    for i in range(5000000):
        yield 'hsr'

g = generate_hsr()
for i in g:
    print(i)

5、send

#send获取下一个值,传值给上一个yield
#第一次使用生成器用next
最后一个yield不能接受传值
def generator():
    print(123)
    content = yield 1
    print(content)
    yield 2

g = generator()
ret1 = g.__next__()    #ret1 =1
ret2 = g.send('hsr')    #输出hsr 并 ret2 = 2

6、计算移动平均值

def avg_generator():
    sum = 0
    count = 0
    avg = 0
    while 1:
        num = yield avg
        count += 1
        sum += num
        avg = sum / count

g = avg_generator()
r = g.__next__()
print(r)
for i in range(5):
    ret = g.send(int(input()))
    print(ret)

6、预激协程的装饰器

# 用装饰器进行一次next,后面就可以直接使用
def init(func):
    def inner(*args,**kwargs):
        g = func(*args,**kwargs)
        g.__next__()
        return g
    return inner
@init
def avg_generator():
    sum = 0
    avg = 0
    count = 0
    while 1:
        num = yield avg
        count += 1
        sum += num
        avg = sum / count
g = avg_generator()
print(g.send(10))
print(g.send(15))
print(g.send(20))

7、yield from

#可以从容器中直接一个一个返回值
def generator():
    l = [1,2,3,4,5]
    yield from l

g = generator()
for i in g:
    print(i)

#结果
1
2
3
4
5

9、列表推导式

#形式
#[满足条件的元素 for 元素 in 可迭代对象 if 条件]

li = [i for i in range(31) if i % 3 == 0]
#得到30内可以被3整除的数的列表

#嵌套
li2 = [[1,2,3,4,5],[6,7,8,9,10]]
ret = [i for ls in li2 for i in ls if i %2 == 0]
#得到嵌套列表中可以被2整除的数的列表

10、生成器表达式

#和列表推导式类似,将[]换成()
#不同的是生成器表达式得到的是一个迭代器,而不是全部的数据

g = (i for i in range(10))
print(g)    #会得到类似<generator object generator ...>

#可以使用for循环获取值
for i in g:
    print(i)

11、字典推导式

#以将键值对换为例(注意值要是不可迭代对象)

dic = {'a':10,'b':20}

dic_frequency = {dic[k]:k for k in dic}

12、集合推导式

#和列表推导式类似,将[]换成{},结果会去重

squared = { x**2 for i in [1,-1,2]}
#结果 squared = {1,4}

 

posted @ 2019-02-14 17:43  WaltHwang  阅读(156)  评论(0编辑  收藏  举报