python 迭代器
- 迭代器可以记住遍历的位置
- 迭代器只能前进不能后退
- 迭代器对象从第一个元素开始访问,直到所有元素被访问完
- 列表、元组、字典、集合、字符串均属于可迭代对象
from collections import Iterable,Iterator
#Iterable,Iterator:前者用于判断对象是否是一个可迭代对象,后者用于判断是否是一个迭代器
# 列表是可迭代对象,所以下面的print打印True
x = [1, 2, 3, 45, 'asd']
print(isinstance(x, Iterable))
>>>True
通过列表推倒式获取迭代器,将[]改为()则获得最简易的生成器
y = [x for x in range(10)] # 迭代器
z = (x for x in range(10)) # 生成器
print(type(y)) >>> <class 'list'>
print(type(z)) >>> <class 'generator'>
print(isinstance(z, Iterable)) >>>True
print(isinstance(z, Iterable)) >>>True
print(isinstance(y, Iterator)) >>>False
print(isinstance(z, Iterator)) >>>True
由上可知:y是一个可迭代对象,但是不一个迭代器
迭代器可以通过__next__方法遍历,但如果超过迭代对象本身的范围,就会报StopIteration错误
a = 'hello'
b = a.__iter__()
print(b.__next__()) >>> h
print(b.__next__()) >>> e
print(b.__next__()) >>> l
print(b.__next__()) >>> l
print(b.__next__()) >>> o
print(b.__next__()) >>> 报错,StopIteration超出范围,停止迭代
下面实现类,以实现迭代功能
class MyList(object):
def __init__(self):
self.newlist = list()
def append_item(self, data):
"""
该方法实现了增加一个元素到列表到末尾
:param data:
:return:
"""
self.newlist.append(data)
def __iter__(self):
"""
__iter__表示该类实力化的对象是一个可迭代对象,这个魔法方法获取的是__iter__方法中的迭代器
:return:
"""
iterobj = MyIterator(self.newlist)
return iterobj
lass MyIterator(object):
"""
这个类实现的是迭代器的类
"""
def __init__(self, newlist):
self.newlist = newlist
self.current_index = 0 # 记录当前迭代的索引
def __iter__(self):
return self
def __next__(self):
"""
当前的魔法方法用来记录遍历的位置,第二功能记录需要获取的值
:return:
"""
if self.current_index < len(self.newlist):
self.current_index += 1
return self.newlist[self.current_index - 1]
else:
raise StopIteration # for循环自动捕获到StopIteration后自动结束循环
list1 = MyList()
print(isinstance(list1, Iterable))
print(iter(list1)) # 报错,说明可迭代对象并不一定有迭代器
# todo 可迭代对象不一定是迭代器,但迭代器一定是可迭代对象!
# 1)可迭代对象包含迭代器。
# 2)如果一个对象拥有__iter__方法,其是可迭代对象;如果一个对象拥有next方法,其是迭代器。
# 3)定义可迭代对象,必须实现__iter__方法;定义迭代器,必须实现__iter__和next方法。
obj = MyIterator([1, 2, 3, 4, 5])
for i in obj:
print(i)
- for循环的本质:如果对象是一个迭代器,则直接遍历,若是一个可迭代对象,则先通过iter()寻找迭代器,然后再遍历
- iter() 获取的是对象内部的__iter__魔术方法,在里面一般写为 return self
- next() 获取的是对象内部的 __next__魔术方法,第一个功能是记录了访问位置,第二个功能则是将访问的数据返回