python—迭代器、生成器

1、迭代器(iteration)

迭代器协议:提供next()方法,该方法要么返回迭代的下一项,要么异常。(只能往后走)

可迭代对象:实现迭代器协议的对象。

**字符串、列表、元祖、字典、集合、文件都不是可迭代对象,但在for循环中使用_iter_方法,可以变成可迭代对象。

**for循环可调用可迭代对象的_next_方法取值,且会捕捉异常

x = 'hello'
## 生成迭代器对象
iter_test = x.__iter__()
print(iter_test)  ##  <str_iterator object at 0x00419FB0>
## next()去列表的值,取不到以后,会报异常
print(iter_test.__next__()) ##  h
print(iter_test.__next__()) ##  e

## for
for i in x:
    print(i)

  

x = ['aaa','bbb','ccc']
## 生成迭代器对象
iter_test = x.__iter__()
## next()方法就是调用_next_()方法
print(next(iter_test))

  

2、生成器(generator)

一种数据类型,是可迭代对象 

## 三元表达式
name = 'Amy'
res='yes' if name =='Amy' else 'no'
print(res) ## 如果true,返回yes,否则返回no

  

## 列表解析
li = []
for i in range(10):
    li.append('嘟嘟%s'%i)
print(li)

print(['嘟嘟%s'%i for i in range(10)])

print(['嘟嘟%s'%i for i in range(10) if i > 5 ])

  

(1)、生成器函数

yield返回结果,而不是return

## 生成器函数,可以返回多次
def test():
    yield 1
    yield 2

t = test()
print(t)  ## <generator object test at 0x005D0EB0>
print(t.__next__()) ##  1
print(t.__next__()) ## 2

  

(2)、生成器表达式

把列表解析的[ ]  变成 ()

## 生成器表达式
s = ('嘟嘟%s'%i for i in range(10))
print(s)  ##  <generator object <genexpr> at 0x00400E70>
print(s.__next__()) ## 嘟嘟0
print(next(s))  ## 嘟嘟1

  

 

def eggs():
    li = []
    for i in range(100):
        li.append('egg%s' %i)
    return  li

print(eggs())
## 缺点:占空间大;效率低


## 生成器 改进
def eggs():
    for i in range(100):
        yield  'egg%s' %i

s = eggs()
print(next(s))
print(next(s))

  

生成器优点:

1、延迟计算,一次返回一个结果,不会一次生成所有结果,对于大数据处理非常有用;

— 列表解析:内存占用大,机器容易卡死

— 声称其表达式:几乎不占内存

2、提高代码可读性

 

## a.txt 内容
## {'name':'北京','population':13}
## {'name':'福建','population':1645}
## {'name':'安徽','population':642}
## {'name':'河南','population':146}
## {'name':'河北','population':435}


def get_population():
    ret = []
    with open('a.txt','r',encoding='utf-8') as f:
        for i in f:
            yield i

p = get_population()
print(eval(next(p))['name'])
print('总人口:',sum(eval(i)['population'] for i in p))

  

3、生产者消费者模型

send() 方法

# yield 3 — 相当于return  函数的返回值
# x = yield  — 接收send传过来的值,赋值给yield
def test():
    print('开始')
    first = yield 1  ## return 1   first=None
    print('第一次',first)
    yield 2
    print('第二次')

t = test()
print(next(t)) ## 执行到 first = yield 1
#  开始
#  1
print(t.send(None))  ## 把None传给first,在执行到 yield 2
# 第一次 None
# 2

  

## 生产者消费者模型

import time
def producer():
    ret = []
    for i in range(10):
        time.sleep(0.1)
        ret.append('产品%s' %i)
    return ret

def consumer(res):
    for index,product in enumerate(res):
        print('第%s个顾客,购买%s' %(index,product))

res = producer()
consumer(res)



###  并发
def consumer(name):
    print('我是【%s】,要购买产品' %name)
    while True:
        product = yield
        print ('%s 购买了【%s】' %(name,product))

def producer():
    c1 = consumer('Amy')
    next(c1)
    for i in range(10):
        c1.send('产品%s' %i)

producer()

  

 

 

posted @ 2019-01-15 17:04  kuluma  阅读(169)  评论(0编辑  收藏  举报