迭代器的基本作用:可以通过其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)
while True:
try:
print(next(myTuple_iter))
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)
while True:
try:
key = next(myDict_iter)
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)
while True:
try:
print(next(myRange_iter))
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)
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):
print('{}: {}'.format(i,ch))
print('\niterator for reversed():')
characters = ['a','b','c']
for ch in reversed(characters):
print(ch)
运行结果:
iterator for enumerate():
0: a
1: b
2: 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
fibs = Fibs()
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
if self.value > self.num:
raise StopIteration
return self.value
def __iter__(self):
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)
def __iter__(self):
return self
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))
for j in range(1,6):
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))
for num in dataiter:
print(num)
iter(self)方法的作用就是,能够返回一个迭代器: (1)如果没有__iter__(self)方法,就会提示TypeError: 'DataIter' object is not iterable (2)即使没有__iter__(self)方法,但是类中next()方法仍然存在,因此采用while循环的方法,仍然可以实现遍历整个序列
|