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

迭代器介绍

时间:2020-04-09 22:54:39      阅读:132      评论:0      收藏:0      [点我收藏+]

标签:结果   长度   none   imp   iterator   元素   name   net   rest   

迭代器简介:迭代是访问集合元素的一种方式。迭代器是一个可以记住遍历的位置的对象。迭代器对象从集合的第一个元素开始访问,直到所有的元素被访问完结束。迭代器只能往前不会后退。

for循环执行步骤:1.判断对象是否是可迭代的(创建对象的类要有__iter__方法)

                              2.判断对象的__iter__方法的返回值是一个迭代器(返回值有__iter__和__next__ 方法的引用)

                              3.每次循环调用__next__方法的返回值

初次自定义迭代对象:

 1 class Classmate(object):
 2     def __init__(self):
 3         self.names = list()
 4 
 5     def add(self, name):
 6         self.names.append(name)
 7 
 8 
 9 classmate = Classmate()
10 classmate.add("张三")
11 classmate.add("李四")
12 classmate.add("王五")
13 
14 for temp in classmate:
15     print(temp)

  运行结果报错:Classmate不是可以迭代的

  说明:for循环执行首先会判断对象是否为可迭代的

1 TypeError: Classmate object is not iterable

Classmate类中添加__iter__方法,在循环前加上判断classmate是否是可迭代:

1     def __iter__(self):
2         pass
3 
4 ......
5 
6 print(classmate是否是可迭代的:, isinstance(classmate, Iterable))

  运行报错:iter()返回类型为非迭代器

  说明:for循环判断为可迭代的对象后,会判断对象的iter方法的返回值是否有__iter__和__next__ 方法的引用

1 classmate是否是可迭代的: True
2 TypeError: iter() returned non-iterator of type NoneType

将Classmate类中的__iter__的返回值添加含__iter__ 和__next__ 方法的引用:

 1 from collections.abc import Iterable
 2 from collections.abc import Iterator
 3 
 4 
 5 class Classmate(object):
 6     def __init__(self):
 7         self.names = list()
 8 
 9     def add(self, name):
10         self.names.append(name)
11 
12     def __iter__(self):
13         # ClassIterator()相当于创建ClassIterator的对象,return这个对象相当于返回这个对象的引用
14         return ClassIterator()
15 
16 
17 class ClassIterator(object):
18     def __iter__(self):
19         pass
20 
21     def __next__(self):
22         pass
23 
24 
25 classmate = Classmate()
26 classmate.add("张三")
27 classmate.add("李四")
28 classmate.add("王五")
29 
30 
31 # print(‘classmate是否是可迭代的:‘, isinstance(classmate, Iterable))
32 classmate_iterator = iter(classmate)   # iter(classmate)可以接收_iter__方法的返回值
33 print(classmate_iterator是否是迭代器:, isinstance(classmate_iterator, Iterator))
34 
35 
36 for temp in classmate:
37     print(temp)

  运行结果:

  说明:都判断为True后开始循环取next方法的返回值

1 True
2 None
3 None
4 None
5 None
6 ......

由此,通过设置next方法的返回值可以改变for循环执行的结果。如果要让for循环正确执行,next方法的返回值设置思路为:

  1.通过classmate[索引]取得classmate内的元素

  2.索引要从0到classmate的元素长度减1,且调用一次next,索引加1

  3.通过raise StopIteration 抛出StopIteration异常告诉for循环已经循环结束。此时索引是大于等于classmate元素的长度

for循环要正确执行代码修改如下:

 1 class Classmate(object):
 2     def __init__(self):
 3         self.names = list()
 4 
 5     def add(self, name):
 6         self.names.append(name)
 7 
 8     def __iter__(self):
 9         # ClassIterator()相当于创建ClassIterator的对象,return这个对象相当于返回这个对象的引用
10         # ClassIterator(self)将自己作为实参传递到ClassIterator这个类
11         # 当ClassIterator类的init方法用 self.名称=形参 时,ClassIterator类的 self.名称 将指向我自己
12         return ClassIterator(self)
13 
14 
15 class ClassIterator(object):
16 
17     def __init__(self, obj):
18         self.obj = obj
19         self.num = 0
20 
21     def __iter__(self):
22         pass
23 
24     def __next__(self):
25         if self.num < len(self.obj.names):
26             rest = self.obj.names[self.num]
27             self.num += 1
28             return rest
29         else:
30             raise StopIteration
31 
32 
33 classmate = Classmate()
34 classmate.add("张三")
35 classmate.add("李四")
36 classmate.add("王五")
37 
38 
39 # print(‘classmate是否是可迭代的:‘, isinstance(classmate, Iterable))
40 # classmate_iterator = iter(classmate)
41 # print(‘classmate_iterator是否是迭代器:‘, isinstance(classmate_iterator, Iterator))
42 
43 
44 for temp in classmate:
45     print(temp)

  运行结果:

1 张三
2 李四
3 王五

可以将Classmate类里面的__iter__方法的返回值设置成自己(self),那么在Classmate类里面添加__next__方法并设置返回值也可以将对象的__iter__方法的返回值设置为一个迭代器,这样精简了代码:

 1 class Classmate(object):
 2     def __init__(self):
 3         self.names = list()
 4 
 5     def add(self, name):
 6         self.names.append(name)
 7         self.num = 0
 8 
 9     def __iter__(self):
10         return self
11 
12     def __next__(self):
13         if self.num < len(self.names):
14             rest = self.names[self.num]
15             self.num += 1
16             return rest
17         else:
18             raise StopIteration
19 
20 
21 classmate = Classmate()
22 classmate.add("张三")
23 classmate.add("李四")
24 classmate.add("王五")
25 
26 for temp in classmate:
27     print(temp)

  运行结果:

1 张三
2 李四
3 王五

迭代器介绍

标签:结果   长度   none   imp   iterator   元素   name   net   rest   

原文地址:https://www.cnblogs.com/zuzhuangmengxiang/p/12670237.html

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