码迷,mamicode.com
首页 > 其他好文 > 详细

迭代器与生成器

时间:2021-03-16 12:00:59      阅读:0      评论:0      收藏:0      [点我收藏+]

标签:时间   init   ror   imp   说明   属性   中间   turn   获取   


# 1.可迭代对象
# 能被for循环遍历取值的数据类型:list/str/tuple/dict/set
# 遍历(迭代):可迭代对象使用for.. in..的循环语法从其中依次拿到数据使用的过程

# for i in 可迭代对象:
# li = [1, 2, 3]
# for i in li: # 遍历取值
# print(i)

# 可迭代对象:
# 泛指一类对象, 满足以下条件的对象可以成为可迭代对象:
# 1.对象实现了__iter__方法
# 2.__iter__方法返回了迭代器对象

# 2.for循环工作原理
# 1.在内部对可迭代对象调用__iter__方法, 获取到迭代器对象
# 2.再一次次的通过迭代器对象,调用__next__方法获取结果

# tu = (‘a‘, ‘b‘, ‘c‘) # 可迭代对象
# for i in tu:
# print(i)

# 3. 如果判断一个对象是否可以迭代 --- isinstance()
# 可迭代对象:Iterable
# isinstance()

# 可迭代对象其实都是collections模块里面的Iterable类创建出来的实例
from collections.abc import Iterable # 导入模块

# name = ‘jiuge‘
# print(isinstance(name, Iterable)) # 该对象是可迭代对象,返回为True
# print(isinstance(123, Iterable)) # 该对象不是可迭代对象,返回为False

# 4.迭代器 Iterator
# 迭代器就是实现了__iter__和 __next__方法的对象
# 迭代器有两个函数: iter() 和 next()

# 遍历取值步骤:
# 1.先调用对象的iter函数:
# iter()直接调用该对象的__iter__方法,并把该方法的返回结果作为自己的返回值
# 2.再使用next()函数来调用__next__方法
# 3.元素取完后,__next__方法会引发StopIteration异常

li = [‘大海星辰‘, ‘活出自己‘, ‘好男人不止是曾小贤‘, ‘原来是美男吖‘]

# 创建迭代器对象
# it = iter(li) # 1.通过iter方法转换迭代器对象
# print(it)

# 输出元素
# print(next(it)) # 2.对获取到的迭代器对象不断使用next方法获取下一条数据
# print(next(it))
# print(next(it))
# print(next(it))
# print(next(it)) # 3.取完元素后,再去取引发StopIteration异常


tu = (1, 2, 3, 4)
ut = tu.__iter__()
# print(ut)
# print(ut.__next__())
# print(ut.__next__())
# print(ut.__next__())
# print(ut.__next__())

# try:
# while True:
# print(ut.__next__())
#
# except:
# print(‘数据已经取完了‘)

 


# 5.可迭代对象和迭代器对象
# 可迭代对象:Iterable
# 迭代器对象:Iterator
# isinstance()判断的函数

from collections.abc import Iterable, Iterator # 导入模块

st = ‘python‘
# print(isinstance(st, Iterable)) # True st是可迭代对象
# print(isinstance(st, Iterator)) # False st不是迭代器对象

it = iter(st)
# print(it) # <str_iterator object at 0x000002397E9F24C8>
print(isinstance(it, Iterable)) # True it是可迭代对象
print(isinstance(it, Iterator)) # True it是迭代器对象

# 总结:
# 迭代器对象一定是可迭代对象,可迭代对象不一定是迭代器对象

# 可迭代对象可以通过方法变成迭代器对象 (水果可以通过工厂变成水果罐头)

 

 

 


# 1.迭代器协议

# 概念:
# 对象必须提供一个next方法,执行该方法要么返回下一项,要么引起StopIteration异常

# 条件:
# 1.对象实现__next__方法
# 2.next方法放了某个数据
# 3.数据取完的时候,抛出StopIteration异常

# 迭代器对象是实现了迭代器协议的对象

# 2.自定义迭代器类
# 需要有两个特性:
# 2.1 具有iter方法,返回迭代器对象本身(类中定义了iter方法,这个类的实例就是一个迭代器对象)
# 2.2 具有next方法,返回下一个元素或者抛出StopIteration异常

# 自定义类,实例化的对象不能使用for循环遍历取值
class Test:
def __init__(self):
self.n = 0 # 定义一个初始值n

def funa(self): # 实例方法
# print(‘这是funa方法‘)
self.n += 1
return self.n


# # 实例化对象
# te = Test()
#
# for i in te: # TypeError: ‘Test‘ object is not iterable
# print(i)


# 修改后,实例对象可以通过for循环遍历取值
class Test2:

# 返回迭代器对象
def __iter__(self):
self.n = 0
return self # 返回的是当前的实例对象,也就是迭代器对象

# 返回的是要取的数据
def __next__(self):
# 第二种:
if self.n == 6: # 设置条件,n的值为6时,抛出异常
# 抛出异常
raise StopIteration(‘超出范围了‘)
self.n += 1
return self.n


te2 = Test2()
# 直接调用next方法报错,没有调用iter方法,实例属性self.n没有生成
it = iter(te2)
while True:
print(next(it))

 

# 第一种:
# for循环中加结束条件
# for i in te2:
# if i <= 10:
# print(i)
# else:
# break

# 第二种:
# for i in te2:
# print(i)

 


# 1.生成器函数
# 生成器就是一种自定义的迭代器,本质是迭代器

# 定义方式:
# 1.1 生成器表达式:类似列表推导式

li = [i*2 for i in range(3)] # 列表推导式
# print(li) # [0, 2, 4]

li2 = (i*2 for i in range(3)) # 生成器表达式
# print(li2) # <generator object <genexpr> at 0x000002631B3A7DC8>
# print(next(li2))


# for i in li2:
# print(i)

# 1.2 生成器函数
# yield:每次返回一个结果,在每个结果中间,挂起函数,以便下次从它离开的地方继续执行

# yield使函数中断,并保存中断的状态,中断后代码可以继续往下执行,过一段时间还可以重新调用这个函数

def test():
print(‘开始了...‘)
yield 123 # 返回一个值‘a‘, 暂停函数
yield ‘b‘
yield ‘c‘

t = test() # t是生成器对象
# print(t) # <generator object test at 0x000002A492327DC8>
# print(next(t))
# print(next(t))
# print(next(t))
# print(next(t))


# for i in t:
# print(i)


# 2. return和yield

# 如果生成器函数中有return,return返回的值是StopIteration异常的说明
def funa():
yield 123
return ‘这是return‘

a = funa()
print(next(a))
print(next(a))


# 大概还有6节课
# 关于考试重点:数据类型,函数、面向对象,文件操作
# 考试题型:选择题、代码题

 

迭代器与生成器

标签:时间   init   ror   imp   说明   属性   中间   turn   获取   

原文地址:https://www.cnblogs.com/Daveb/p/14532552.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!