python3迭代器使用小结
迭代器的基本作用:可以通过其next()方法遍历一个序列。
迭代器 (Iterator) \text{(Iterator)} (Iterator)规则:
(
1
)
(1)
(1) 方法__iter__返回一个迭代器,它是包含__next__方法的对象,调用该方法时可不提供任何参数,使用 it = iter(data)
与 it = data.__iter__()
等效。
(
2
)
(2)
(2) 当调用方法__next__时,迭代器返回data数据的下一个值,使用 next(it)
与 it.__next__()
等效;如果迭代器没有可供返回的值,会引发StopIteration
异常。
也就是说,__iter__方法返回了一个实现了__next__方法的迭代器对象。
基本python类型的迭代器遍历
\qquad 一些常用函数都实现了迭代接口,可以直接使用。
∙ \bullet ∙ 列表
第一种方式:常用方式
print('iterator for List:')
myList = [123, 23, 34.56]
print(myList)
myList_iter = iter(myList)
while True:
try:
print(next(myList_iter))
except StopIteration:
break
第二种方式:
使用 myList.__iter__() 与 iter(myList) 等效
使用 myList_iter.__next__() 与 next(myList_iter) 等效
print('iterator for List:')
myList = [123, 23, 34.56]
print(myList)
myList_iter = myList.__iter__()
while True:
try:
print(myList_iter.__next__())
except StopIteration:
break
第三种方式:使用for循环自动迭代,for循环会访问一个可迭代对象(序列或迭代器)中的所有元素
print('iterator for List:')
myList = [123, 23, 34.56]
print(myList)
myList_iter = iter(myList)
for i in myList_iter:
print(i)
运行结果:
iterator for List:
[123, 23, 34.56]
123
23
34.56
∙ \bullet ∙ 元组
print('\niterator for Tuple:')
myTuple = (123, 'xyz', 34.56)
print(myTuple)
myTuple_iter = iter(myTuple) # 或者 myTuple_iter = myTuple.__iter__()
while True:
try:
print(next(myTuple_iter)) # 或者 print(myTuple_iter.__next__())
except StopIteration:
break
或者直接使用for循环自动迭代
print('\niterator for Tuple:')
myTuple = (123, 'xyz', 34.56)
print(myTuple)
myTuple_iter = iter(myTuple)
for i in myTuple_iter:
print(i)
运行结果:
iterator for Tuple:
(123, 'xyz', 34.56)
123
xyz
34.56
∙ \bullet ∙ 字典,字典的迭代器遍历的是key值
print('\niterator for Dictionary:')
myDict = {'a': 1, 'b': 2, 'c': 3}
# 一般方式:
for key in myDict:
print(key, ':', myDict[key])
# 迭代器:
myDict_iter = iter(myDict) # 或者 myDict_iter = myDict.__iter__()
while True:
try:
key = next(myDict_iter) # 或者 key = myDict_iter.__next__()
print(key, ':', myDict[key])
except StopIteration:
break
或者直接使用for循环自动迭代
print('\niterator for Dictionary:')
myDict = {'a': 1, 'b': 2, 'c': 3}
myDict_iter = iter(myDict)
for key in myDict_iter:
print(key, ':', myDict[key])
运行结果:
iterator for Dictionary:
a : 1
b : 2
c : 3
∙ \bullet ∙ Range(a,b)
print('\niterator for Range(a,b):')
myRange = range(3,6)
print(list(myRange))
myRange_iter = iter(myRange) # 或者 myRange_iter = myRange.__iter__()
while True:
try:
print(next(myRange_iter)) # 或者 print(myRange_iter.__next__())
except StopIteration:
break
或者直接使用for循环自动迭代
print('\niterator for Range(a,b):')
myRange = range(3,6)
# 一般方式:
for i in myRange:
print(i)
print(list(myRange))
myRange_iter = iter(myRange) # 或者 myRange_iter = myRange.__iter__()
for i in myRange_iter:
print(i)
运行结果:
iterator for Range(a,b):
3
4
5
[3, 4, 5]
3
4
5
∙ \bullet ∙ 与for循环类似的还有Range(a,b)函数、enumerate()函数、reversed()函数等,都可以实现自动迭代
print('\niterator for enumerate():')
characters = ['a','b','c']
for i, ch in enumerate(characters): # for i, ch in enumerate(characters,3):
print('{}: {}'.format(i,ch))
print('\niterator for reversed():')
characters = ['a','b','c']
for ch in reversed(characters):
print(ch)
运行结果:
iterator for enumerate():
0: a # 3: a
1: b # 4: b
2: c # 5: c
iterator for reversed():
c
b
a
\quad
使用类创建迭代器
\qquad
通过定义类中的__iter__()和__next__()方法,来创建一个迭代器。
\quad
例1 斐波那切数列:0、1、1、2、3、5、8、13、21、34、…
例子中通过自定义的迭代器,找到第一个大于10的斐波那切数(13)。
class Fibs:
def __init__(self):
self.a = 0
self.b = 1
def __next__(self): # 调用该方法时可不提供任何参数
self.a, self.b = self.b, self.a+self.b
return self.a
def __iter__(self): # 返回一个迭代器
return self # self 是包含 __next__()方法 的对象
fibs = Fibs() # 返回一个迭代器,迭代器会自动调用__next__()方法
for f in fibs:
if f>10:
print(f)
break
运行结果:
13
\quad
例2 使用迭代器创建列表
class ListIterator:
value = 0
def __init__(self, num):
self.num = num
def __next__(self):
self.value += 1
# print(self.value)
if self.value > self.num:
raise StopIteration
return self.value
def __iter__(self):
# print(self.value,'iter')
return self
ti = ListIterator(10)
print(list(ti))
运行结果:
[1, 2, 3, 4, 5, 6, 7, 8, 9, 10]
\quad
例3 需要提供参数的__next__方法
class AnyIter:
def __init__(self, data):
self.iter = iter(data) # 直接采用已有迭代器来遍历data
def __iter__(self):
return self
# __next__方法需要提供参数
def __next__(self, howmany=1):
retval = []
for item in range(howmany):
try:
retval.append(next(self.iter))
except StopIteration:
break
return retval
anyiter = AnyIter(range(14)) # 返回一个迭代器,自动调用__next__(self, howmany=1)方法
for j in range(1,6): # 每次遍历j个数,第j+1次遍历的起点是第j次遍历的下一个值
print('{}: {}'.format(j, anyiter.__next__(j)))
运行结果:
1: [0] # anyiter迭代器可以遍历序列 0,1,...,13
2: [1, 2]
3: [3, 4, 5]
4: [6, 7, 8, 9]
5: [10, 11, 12, 13] # 第5次遍历,由于输入数据不够,只能显示列表中剩下的数据
\quad
迭代器分析
这是一个和例2几乎相同的例子
class DataIter:
def __init__(self, data):
self.data = data
self.index = 0
def __iter__(self):
return self
def __next__(self):
if not self.data or self.index >= len(self.data):
raise StopIteration
val = self.data[self.index]
self.index += 1
return val
dataiter = DataIter(range(5))
# while True:
# try:
# print(next(dataiter))
# except StopIteration:
# break
for num in dataiter:
print(num)
iter(self)方法的作用就是,能够返回一个迭代器:
(1)如果没有__iter__(self)方法,就会提示TypeError: 'DataIter' object is not iterable
(2)即使没有__iter__(self)方法,但是类中next()方法仍然存在,因此采用while循环的方法,仍然可以实现遍历整个序列