迭代器与生成器

1.迭代器

1.迭代器是一个可以记住遍历的位置的对象。

iterable 可迭代的对象

iterator 迭代器

iter 迭代

int类型中没有__iter__方法,因为int是不可迭代的对象

查看数据类型中的方法:dir([object])

2.迭代器的特点:

1.只能向前

2.几乎不占内存,节省内存

3.惰性机制

4.可以for循环

3.迭代器中的常用方法__iter__()创建迭代器,__next__()输出迭代器的下一个元素4.迭代器模拟for循环

li = "1234"
a = li.__iter__()  # 创建迭代器
print(a.__next__()) # 输出,调用一次就输入一个元素
<<<<1
print(a.__next__())
<<<<2
print(a.__next__())
<<<<3
print(a.__next__())
<<<<4
# 注意:当后面没有元素可迭代的时候会报错

4.迭代器模拟for循环

lst = ["卢本伟","刘二狗","铁蛋","神仙"]
s = lst.__iter__() # 创建迭代器

while 1:  # 循环,当循环到后面的时候会没有元素就会报错,所以要用异常处理
    try:  #尝试执行   
        a = s.__next__()
        print(a)
    except StopIteration:  # 处理错误
        break
<<<<
卢本伟
刘二狗
铁蛋
神仙

5.判断是否是可迭代对象跟迭代器

lst = ["卢本伟","刘二狗","铁蛋","神仙"]
a = lst.__iter__()
print("__iter__"in dir(lst))  #判断是否是可迭代的对象,可迭代对象方法中只要__iter__,没有__next__
<<<<True
print("__next__" in dir(lst))
<<<<False
print("__next__" and "__iter__"in dir(a))   #判断是否是迭代器,迭代器的方法中__next__与__iter__都有
<<<<True
# 迭代器的方法里面__iter__跟__next__都有
第一种
lst = ["卢本伟","刘二狗","铁蛋","神仙"]
a = lst.__iter__()
from collections.abc import Iterable # 可迭代的 引入模块
print(isinstance(lst,Iterable)) #判断是否是可迭代的
<<<<True
from collections.abc import Iterator #迭代器  引入模块
print(isinstance(a,Iterator))  #判断是否是迭代器
<<<<True
第二种,官方判断方法

 

2.生成器

使用了 yield 的函数被称为生成器(generator)

 

1.如果函数中有yield这个函数,那么这个函数就是生成器函数 ,生成器函数()获取的是生成器,这个时候不执行函数
def func():
    print("娃哈哈")
    yield 1   # 只要函数里用了yield,再调用函数是不会执行函数的
    print("666")
    yield 3
func()
<<<<Process finished with exit code 0

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

def func():
    print("娃哈哈")
    yield 1   # 只要函数里用了yield,再调用函数是不会执行函数的
    print("666")
    yield 3
gen =func()
a =gen.__next__() # 执行到第一个yield然后停止
<<<<娃哈哈
print(a)  # 返回值为1
<<<<1
b =gen.__next__() #执行到下一个yield然后停止
<<<<666
print(b)   # 返回值为3
<<<3

3.send()

send()跟__next__()是一样的,可以执行到下一个yield,可以给上一个yield位置传值,send()里面必须要给值不然会报错

def eat():
    print("我吃什么")
    a = yield "馒头"
    print("a=",a)
    b = yield "鸡蛋灌饼"
    print("b=",b)
    c = yield "韭菜盒子 "
    print("c=",c)
    yield "GAME OVER"   # 最后一个传不了值,因为要传值就要有下一个yield,就会进入死循环
gen = eat()  # 获取迭代器
ret = gen.__next__()   # 第一个不能用send,因为没有前一个yield
<<<<我吃什么
print(ret)
<<<<馒头
ret2 = gen.send("胡椒汤")  # 传给第一个yield,a
<<<<a= 胡椒汤
print(ret2)
<<<<鸡蛋灌饼
ret3 = gen.send("狗粮")  # 传给上一个yield,b
<<<<b= 狗粮
print(ret3)
<<<<韭菜盒子 
ret4 = gen.send("猫粮") # 传给上一个yield,c
<<<<c= 猫粮
print(ret4)
<<<<GAME OVER

上面的运行顺序:

4.生成器可以使用for循环
def fuanc():
    yield 1
    yield 2
    yield 3
    yield 4
for i in fuanc():
    print(i)
 <<<<
1
2
3
4   
# 可以拿值
print(list(fuanc()))
<<<<[1, 2, 3, 4]

3.推导式

1.列表推导式

语法:li=[结果   for   判断]

# 奇数列表
li = [i for i in range(1,20) if i%2==1]
print(li)
<<<< [1, 3, 5, 7, 9, 11, 13, 15, 17, 19]   

2.字典推导式

语法:dic = { k:v for循环 条件筛选}

# key跟value对调
dic ={"jj":"林俊杰","jay":"周杰伦","zs":"赵四","ln":"刘能"}
de = { v:k for k,v in dic.items() }
print(de)
<<<<{'林俊杰': 'jj', '周杰伦': 'jay', '赵四': 'zs', '刘能': 'ln'}

3.生成器表达式

tu = (i for i in range(1,10)) #元组没有推导式,这个是生成器表达式
a = tu.__next__()
print(a)
<<<<1

 

 

 

posted @ 2019-08-06 13:40  tiwe  阅读(156)  评论(0编辑  收藏  举报