本周末,学校的课程终于结束啦!值得庆祝!于是乎,终于有时间可以静下心来,写一些自己的东西啦!
今天依然谈Pyhton,想要谈的主题是python中的可迭代对象(iterable)。
首先来说一下可迭代对象的定义,我们知道,在Python的世界中,一切皆是对象。对象根据定义的维度不同,又可以分为各种不同的类型,譬如有整数对象、浮点数对象,字符串对象还有列表对象等等。
那么,何为可迭代对象呢?一句话,“我们将包含__iter__()方法的对象统称为可迭代对象”。实际编程中,我们常用的可迭代对象主要有:列表、元组、集合与字典和字符串等等。
您可能很奇怪,这个所谓的__iter__()方法到底有什么作用呢?下面让我来给您揭秘。先来看以下代码。
lst01 = [1, 2, 3, 4, 5]
print(lst01.__iter__())
注意,以上代码中,首先定义了一个列表lst01,由于列表是一个可迭代对象,所以他拥有__iter__()方法。程序中,我们调用_iter__()方法,并打印该方法的返回结果,我们发现结果如下。
iterator是迭代器的意思,由此可见,可迭代对象的__iter__()方法的返回值是一个该对象所对应的迭代器。那么迭代器有什么作用呢?再来看代码。
lst01 = [1, 2, 3, 4, 5]
iterator = lst01.__iter__()
while True:
try:
item =iterator.__next__()
print(item)
except:
break
我们发现,lst01的__iter__()方法返回的迭代器iterator可以通过其__next__()方法实现对列表lst01的遍历与迭代。最终,以上代码运行后效果如下。
1
2
3
4
5
你可能发现了,以上代码其实作用与for一致,都起到了遍历lst01中所有元素的作用。对,没错。也就是说以上代码,其实就等价于以下代码。
lst01 = [1, 2, 3, 4, 5]
for item in lst01:
print(item)
这回明白了吗?也就是说,当我们的for循环在遍历可迭代对象时,原理就是分两步走,第一步是利用__iter__()方法返回一个迭代器,第二步就是利用迭代器的__next__()方法来遍历可迭代对象中的元素。具体工作原理如下图所示。
可迭代对象的迭代原理图
好了,如果还不明白,我们不如自己做一个可迭代对象吧。我们知道Python中有一个常用的可迭代对象range对象,他可以产生一定范围内的整数。例如:
for item in range(0,10,1):
print(item)
运行结果为:
0
1
2
3
4
5
6
7
8
9
容易看出,range对象在初始化时,第一个参数代表起始值,第二个参数代表停止值(实际是到第二个参数减1结束),最后一个参数代表间隔值。
接下来我们自制一个可迭代对象。首先先做一个可迭代对象的类。
class MyRange:
def __init__(self, start, stop, step):
data = []
if isinstance(step,float):
str_step = str(step)
digits_num = len('.'.split(str_step)[-1])
else:
digits_num = 0
while start
data.append(start)
start += step
start = round(start, digits_num)
self.data = data
易见,以上定义的类中由于含有了__iter__()方法,所以,当用它在实例化对象时,产生的即为可迭代对象。我们看以上代码中出现的MyRangeIterator对象,该对象为__iter()方法的返回值,所以就是MyRangede的一个迭代器。接下来,我们来写一下这个对象。
class MyRangeIterator:
def __init__(self, data):
self.data = data
self.index = 0
def __next__(self):
if self.index > len(self.data)-1:
raise StopIteration
item = self.data[self.index]
self.index += 1
return item
我们看,这个类中最显眼的就是__next__()方法。有了__next__方法,我们就可以利用for循环来实现对该对象的遍历啦。做个实验。
myRange01 = MyRange(0, 10, 1)
for i in myRange01:
print(i)
以上代码对我们定义的MyRange实例化的可迭代对象进行了遍历,运行后,结果如下。
0
1
2
3
4
5
6
7
8
9
怎么样,结果与Python内置的range对象作用是不是一致。不仅如此,我们做的MyRange对象还可以实现生成一定范围内的小数。看以下实例。
myRange01 = MyRange(0.0, 10.0, 0.1)
for i in myRange01:
print(i)
运行结果为
0.0
0.1
0.2
0.3
0.4
0.5
0.6
0.7
0.8
0.9
1.0
1.1
1.2
1.3
1.4
1.5
1.6
1.7
1.8
1.9
2.0
2.1
2.2
2.3
2.4
2.5
2.6
2.7
2.8
2.9
3.0
3.1
3.2
3.3
3.4
3.5
3.6
3.7
3.8
3.9
4.0
4.1
4.2
4.3
4.4
4.5
4.6
4.7
4.8
4.9
5.0
5.1
5.2
5.3
5.4
5.5
5.6
5.7
5.8
5.9
6.0
6.1
6.2
6.3
6.4
6.5
6.6
6.7
6.8
6.9
7.0
7.1
7.2
7.3
7.4
7.5
7.6
7.7
7.8
7.9
8.0
8.1
8.2
8.3
8.4
8.5
8.6
8.7
8.8
8.9
9.0
9.1
9.2
9.3
9.4
9.5
9.6
9.7
9.8
9.9
好了,暂时就写到这里, 后面我们有时间再谈生成器的具体原理与其实现方法。各位,再会!
-end-
Python 青少年编程
Python教学案例与公益课:
Python微课堂系列: