欢迎访问 生活随笔!

生活随笔

当前位置: 首页 >

python3迭代器和可迭代对象_一文读懂 Python3 可迭代对象、迭代器、生成器区别...

发布时间:2024/9/19 67 豆豆
生活随笔 收集整理的这篇文章主要介绍了 python3迭代器和可迭代对象_一文读懂 Python3 可迭代对象、迭代器、生成器区别... 小编觉得挺不错的,现在分享给大家,帮大家做个参考.

笔者学习Python已有一段时间,一直以为对于可迭代对象(iterable)、迭代器(iterator)、生成器(generator)有一定理解了,直到看到《流畅的python》中的讲解才有了更深的体会,话不多说,开始:

对于可迭代对象和迭代器常规的理解:若对象中实现了 __getitem__ 或者 __iter__ 方法,那么这个对象就是可迭代对象

2. 若对象中实现了 __next__ 和 __iter__ 方法,那么这个对象就是迭代器

3. 可迭代对象的背后其实是迭代器在起作用 (后面会说到)

那么什么是可迭代对象,事实上,python中的所有序列集合都是可迭代对象,并且他们都支持for循环遍历。

>>> s = range(4)

>>> for i in s:

print(i)

0

1

2

3

>>> b = list(range(5))

>>> for i in b:

print(b)

0

1

2

3

4

>>> c = {'A':'a', 'B':'b', 'C':'c'}

>>> for key in c:

print(key)

A

B

C

>>> d = set([1,2,3,4])

>>> for i in d:

print(i)

1

2

3

4

为什么他们能够使用for循环遍历元素,背后就是迭代器在起作用,在执行for循环时,可迭代对象通过iter()生成迭代器,然后遍历迭代器中的元素。如果上述代码不使用for想要达到相同的效果可以这样做(用列表举例说明):

>>> a

[0, 1, 2, 3, 4]

>>> iter_a = iter(a)

>>> while 1:

try:

print(next(iter_a))

except StopIteration: # 获取异常

del iter_a

break

0

1

2

3

4

del 作用是废弃当前迭代器对象,因为迭代器对象遍历一次就无法再遍历了,原因是迭代器对象中的__next__方法,当通过next(a)方法(此处a为迭代器对象)依次获取到a中的所有元素,直到输出StopIteration异常。由于上述在for语句中已经对异常进行了处理,所以我们并不会看到,其实每次执行for语句遍历可迭代对象时都生成了一个迭代器,遍历完后就废弃掉。

其次就是在可迭代对象中的__iter__ 方法是实现了一个迭代器。看下面实现了一个数组对象:

#coding:utf-8

class Array():

def __init__(self, maxsize=20): # 指定数组的长度,默认为20

self.maxsize = maxsize

self._items = [None] * maxsize

def __len__(self): # 查看数组长度

return len(self._items)

def __getitem__(self, index):

if index >= self.maxsize: # 索引从0开始

raise Exception('out of the index')

return self._items[index]

def __setitem__(self, index, item):

if index >= self.maxsize: # 索引从0开始

raise Exception('out of the index')

self._items[index] = item

def clear(self):

for i,value in enumerate(self._items):

self._items[i] = None

def __iter__(self):

for item in self._items:

yield item

def append(self,item): # 尾部添加

self._items += [item]

在数组对象中实现了__iter__方法,在此方法中利用yield实现了生成器(生成器和迭代器在一般情况下,没有区别。可以说所有生成器对象都是迭代器对象,有一点细微的区别:生成器对象更倾向于在无限中集合中惰性的输出需要的数据,而迭代器更倾向于在实现已知道所有数据的情况下惰性输出需要的数据,恰当的例子就是斐波那契数列,可以用生成器实现一个斐波那契数列,但因为该数列的元素是无限多个,所以说其是迭代器实现的就没有说由生成器实现的说法恰当)

而在迭代器中也实现了__iter__方法,不过在迭代器中的__iter__方法是实现了如下的内容:

def __iter__(self):

return self

在迭代器对象中的__iter__方法,返回了迭代器本身。这样做的原因是,在需要可迭代对象的地方能够使用迭代器。这个话可能有点绕,不过你想:对于可迭代对象,利用for循环其实利用__iter__方法生成了迭代器;那么如果对于迭代器,利用for循环呢,那么不也是利用__iter__方法生成迭代器吗?但是这里不用生成,因为它本身就是迭代器,所以在迭代器对象中的__iter__方法实现了返回了迭代器本身。

判断一个对象是否是迭代器,可以利用collections库中的abc,它封装了API,比如:

>>> from collections import abc

>>> s = range(9)

>>> isinstance(s, abc.Iterator)

False

>>> f = iter(list(s))

>>> isinstance(f, abc.Iterator)

True

如上,当然你也可以使用next()方法直接看能否输出对象中的元素。不过利用上述的方法能够在程序中合理的区分迭代器和可迭代对象哦。

总结

以上是生活随笔为你收集整理的python3迭代器和可迭代对象_一文读懂 Python3 可迭代对象、迭代器、生成器区别...的全部内容,希望文章能够帮你解决所遇到的问题。

如果觉得生活随笔网站内容还不错,欢迎将生活随笔推荐给好友。