什么是python的迭代器,迭代器有什么好处

【前言】

在初级研发或测试面试中总会被问到什么是python的迭代器,有什么好处?这个看似很简单的话题说起来似乎感觉自己并不是特别清楚的能讲出来。所以本文记录下自己查阅很多资料后的总结。

【什么是迭代器】

迭代器是python最强大的功能之一,是访问集合元素的一种方式

1.迭代器协议是指:对象必须提供一个next方法,执行该方法要么返回迭代中的下一项,要么就引起一个stoplteration异常,以终止迭代(只能往后走,不能往前退)

2.可迭代对象:实现了迭代器协议的对象(如何实现:对象内部定义一个__iter__()方法)

3.协议是一种约定,可迭代对象实现了迭代器协议,python的内部工具(如for循环,sum,min,max函数等)使用迭代器协议访问对象。

当我们看到这些概念的时候是不是觉得很抽象?那么在搞清楚迭代器之前到底什么是迭代?

迭代,顾名思义就是指一个重复的过程,每一次重复都是基于上一次结果而来,迭代提供了一种通用的不依赖索引的迭代取值方式。我们可以把它理解为一种只能从前往后进行比遍历的过程,但是可以进行多次遍历,例如我们的for循环。

可迭代对象:在python中一切皆对象,那么哪些是可迭代对象呢?其实很容易理解可以遍历的对象例如:字符串,list,tuple,dic,set等都属于。如果我们无法判断,就只需要记住在python中,但凡内部有__iter__方法的对象,都是可迭代对象。

(1) 查看对象内部方法

使用dir()去判断一个对象有什么方法,dir()会返回一个列表,这个列表中含有该对象的以字符串中的形式所有方法名,只需要查看返回的方法中是否有__iter__方法,如何有则该对象为可迭代对象。

list1 = [1,2,3]
i = 100
print('__iter__' in dir(i))  # False
print('__iter__' in dir(list1))  # True

所以我们可以判断一个对象是不是可迭代对象可以通过判断该对象是不是含有__iter__方法来判断。

可迭代对象的优点:可以直观查看里面的对象,如直接查看列表的内容

可迭代对象缺点:1. 全部内容要加载至内存中,故占用内存;2. 可迭代对象不能迭代取值(除了索引,key外)

针对可迭代对象有人提出质疑,即使除去索引或者key以外,我们可以通过for循环进行取值,是的,通过for循环进行取值,其实for循环在底层做了一个小小的转换,就是先将可迭代对象转换为迭代器,然后再进行取值。

那么到底什么是迭代器呢?

顾名思义就是可以迭代取值的工具。从专业的角度来说:迭代器就是实现了__next__方法,返回序列的下一个元素,如果没有元素了,就会抛出StopIteration异常,python中的迭代器还实现了__iter__方法,因此迭代器也是可以迭代的。

所以简单地说:在python中,内部含有__iter__方法并且含有__next__方法的对象就是迭代器。

如何判断一个对象是不是迭代器,通过dir方法查看其是否具备iter和next方法,如下判断str,list,tuple,dic和文件哪个是迭代器

str1 = 'hello'
list1 = [1, 2, 3]
tup1 = (1, 2, 3)
dic1 = {'name': '太白','age': 18}
f = open('file',encoding='utf-8', mode='w')
print('__iter__' in dir(str1))  # True
print('__iter__' in dir(list1))  # True
print('__iter__' in dir(tup1))  # True
print('__iter__' in dir(dic1))  # True
print('__iter__' in dir(f))  # True

print('__next__' in dir(str1))  # False
print('__next__' in dir(list1))  # False
print('__next__' in dir(tup1))  # False
print('__next__' in dir(dic1))  # False
print('__next__' in dir(f))  # True
f.close()

可以看出只有文件对象是迭代器,其他对象均是可迭代对象。-------到这里再去理解前面的概念容易多了呢

可迭代对象如何转换为迭代器:

可以通过iter()方法或者可迭代对象.__iter__()方法将可迭代对象转为迭代器

list1 = [1, 2, 3]
print(list1.__iter__())

print(iter(list1))


迭代器取值:

可迭代对象是不可以一直迭代取值的(除去索引,切片及key),但是转换为迭代器就可以了,迭代器是利用__next__()进行取值。

list1 = [1,2,3]
obj = list1.__iter__()  #或者通过iter(list1)转换
#print(obj) #
ret = obj.__next__()
print(ret)
1
ret = obj.__next__()
print(ret)
2
ret = obj.__next__()
print(ret)
3
ret = obj.__next__()  #StopIteration
Traceback (most recent call last):
  File "", line 1, in 
StopIteration

#迭代器利用next取值:一个next取对应的一个值,如果迭代器里面的值取完了还要next那就报StopIteration错误

之前提到for循环的对象一定是可迭代对象,因为for循环的内部机制是:将可迭代对象转换为迭代器,然后利用next进行取值,最后利用异常处理处理StopItreration。

使用while模拟for循环的内部机制:

list1 = [1, 2, 3, 4]
obj = iter(list1) #转换位迭代器
while 1:  # 利用while循环,next进行取值
    try:
        print(next(obj))
    except StopIteration:  # 利用异常处理终止循环
        break   

 

【总结】

在python中,内部含有'Iter'方法并且含有'next'方法的对象就是迭代器

迭代器优点:

1. 提供了一种通用不依赖索引的迭代取值方式;

2. 节省内存,迭代器在内存中相当于只占一个数据的空间:因为每次取值都上一条数据会在内存释放,加载当前的此条数据。

迭代器缺点:

1. 因为有next方法,即只能往后取值,不能往前,取值不如按照索引的方式灵活,不能取指定的某一个值;

2. 无法预测迭代器的长度。

 

你可能感兴趣的:(python)