python迭代器,生成器及推导式

迭代器

可迭代对象:整型str,列表list,元组tuple,字典dict,集合set,range()

遵循可迭代协议

for i in 123:
    print(i)
 
结果
Traceback (most recent call last):
  File "D:/python_object/二分法.py", line 62, in <module>
    for i in 123:
TypeError: 'int' object is not iterable  可迭代的

 

判断迭代器

如果对象中有__iter__函数,那么这个对象就遵守可迭代协议,可获得相应的的迭代器

a = 'abc'dir()查看对象的方法和函数 》
print(dir(a))  #
# 在打印结果中寻找__iter__() 如果存在就表示当前的这个类型是个可迭代对象

 

通过isinstence()判断

l = [1,2,3] 《通过isinstence()判断类型,Iterable可迭代对象,Iterator,迭代器》
l_iter = l.__iter__()
from collections import Iterable
from collections import Iterator
print(isinstance(l,Iterable))      #True             #查看是不是可迭代对象
print(isinstance(l,Iterator))      #False            #查看是不是迭代器
print(isinstance(l_iter,Iterator)) #True       
print(isinstance(l_iter,Iterable)) #True

Iterable:可迭代对象. 内部包含__iter__()函数        

Iterator:迭代器. 内部包含__iter__() 同时包含__next__(). 

 

for 循环机制

for循环也叫遍历循环

lst = [1,2,3]    
l = lst.__iter__()      #转化成迭代器
count = 0          
while count<len(lst):  
    print(l.__next__()) 
    count += 1

 

 

lst = [1,2,3,4,5]
l = lst.__iter__()
while 1 :
    try:             # 异常捕获
        print(l.__next__())
    except StopIteration:
        break

 

 

生成器

迭代器一定是可迭代的,但是可迭代的不一定是迭代器。

生成器本质就是迭代器

定义:函数体中存在yield的就是生成器,函数+()就生成器

在python中有三种方式来获取生成器

  1.通过生成器函数

  2.通过各种推到式来实现生成器

  3.通过数据的转换也可以获取生成器

def func():
    print(11)
    return 22
ret = func()
print(ret)
 
# 运行结果:
11
22

def func():  #《将return换成yield就是生成器》 print(11) yield 22 ret = func() print(ret) # 运行结果: <generator object func at 0x000000000265EEB8>
 
def func(): #《生成器可执行__next__(),生成器只能依次行下运行
print(11)
yield 22
generator = func()
ret = generator.__next__()
print(ret)
# 11
# 22

 

 

def func():
    print("111")
    yield 222
    print("333")
    yield 444

gener
= func()
ret
= gener.__next__() print(ret) ret2 = gener.__next__() print(ret2) ret3 = gener.__next__()  #最后一个yield执行完毕,再次执行__next__()会报错
print(ret3)

 

.send()

send和__next__()一样都可以让生成器执行下一个yield

send(a)可以将a传递给上一个yield,所以send在执行第一个yield时不能有传值,应为空send(None)

def func():
    print("第一个yield前")
    a = yield "a"
    print(f"第二个yield前{a}")
    b = yield "b"
    print(f"第三个yield前{b}")
    c = yield "c"
    print(f"第三个yield后{c}")
f = func()
f.send(None)
f.send("B")
next(f)

# 第一个yield前
# 第二个yield前B
# 第三个yield前None

yield分段执行一个函数,最后一个yield下边的代码可写,但不会被执行

for循环(遍历)

def func():
    yield 'a'
    yield 'b'
    yield 'c'
    yield 'd'
    yield 'e'
f = func()
for i in f:
    print(i)
# a
# b
# c
# d
# e

 

yield from

在python3中可以直接把可迭代对象中的每一个数据作为生成器的结果进行返回

def func():
    lis=[1,2,3,4,5]
    yield from lis
f = func()
for i in f:
    print(i)
# 1
# 2
# 3
# 4
# 5

 

可用__next__()和next(),不能用send()

推导式

列表推导式

[结果 for 变量 in 可迭代对象]

[结果 for 变量 in 可迭代对象 if 判断]

可添加多个for,多个if判断,可以结构赋值,不能有冒号

print([x+y for x,y in [(1,2),(3,4),(5,6)]])
#[3,7,11]

 

字典推导式

list1=[1,2,3,4]
list2=['a','b','c','d']
print({list1[x]:list2[x] for x in range(len(list1))})
# {1: 'a', 2: 'b', 3: 'c', 4: 'd'}

 

集合推导式

print({x+y for x,y in [(1,2),(3,4),(5,6)]})
#{3,7,11}

 

 

生成器推导式

(结果 for 变量 in 可迭代对象)

(结果 for 变量 in 可迭代对象 if 判断)

生成器表达式和列表推导式的区别:

1. 列表推导式比较耗内存,一次性加载.生成器表达式几乎不占用内存.使用的时候才分配和使用内存

2. 得到的值不一样,列表推导式得到的是一个列表.生成器表达式获取的是一个生成器

生成器的惰性机制: 生成器只有在访问的时候才取值,说白了.你找他要才给你值.不找他要.他是不会执行的.

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

迭代器

posted on 2019-01-15 22:16  六月_海动  阅读(128)  评论(0)    收藏  举报