Featured image of post Python迭代对象和迭代器

Python迭代对象和迭代器

、可迭代对象、可迭代对象定义对于迭代器来说,我们更熟悉的应该是可迭代对象,之前无论是源码还是讲课中或多或少我们提到过可迭代对象这个词。之前为了便于大家理解可迭代对象,可能解释的不是很正确,所以今天我们。。。。。。。

1、可迭代对象

1)、可迭代对象定义

对于迭代器来说,我们更熟悉的应该是可迭代对象,之前无论是源码还是讲课中或多或少我们提到过可迭代对象这个词。之前为了便于大家理解可迭代对象,可能解释的不是很正确,所以今天我们正式的聊一聊什么是可迭代对象。从字面意思来说,我们先对其进行拆解:什么是对象?Python中一切皆对象,之前我们讲过的一个变量,一个列表,一个字符串,文件句柄,函数名等等都可称作一个对象,其实一个对象就是一个实例,就是一个实实在在的东西。那么什么叫迭代?其实我们在日常生活中经常遇到迭代这个词儿,更新迭代等等,迭代就是一个重复的过程,但是不能是单纯的重复(如果只是单纯的重复那么他与循环没有什么区别)每次重复都是基于上一次的结果而来。比如你爹生你,你生你爹,哦不对,你生你儿子,你儿子生你孙子等等,每一代都是不一样的;还有你使用过得app,微信,抖音等,隔一段时间就会基于上一次做一些更新,那么这就是迭代。可迭代对象从字面意思来说就是一个可以重复取值的实实在在的东西。

   str  list   tuple  dic  set  range 文件句柄等,那么int,bool这些为什么不能称为可迭代对象呢?虽然在字面意思这些看着不符合,但是我们要有一定的判断标准或者规则去判断该对象是不是可迭代对象。

   在python中,但凡内部含有__iter__方法的对象,都是可迭代对象

2、 查看对象内部方法

该对象内部含有什么方法除了看源码还有什么其他的解决方式么?当然有了, 可以通过dir() 去判断一个对象具有什么方法

1
2
s1 = 'heian'
print(dir(s1))

dir()会返回一个列表,这个列表中含有该对象的以字符串的形式所有方法名。这样我们就可以判断python中的一个对象是不是可迭代对象了:

1
2
3
4
s1 = 'heian'
i = 100
print('__iter__' in dir(i))  # False
print('__iter__' in dir(s1))  # True

3、判断一个对象是否可以迭代

1
2
3
name = [1,2,3,4]
print(dir(name))
print('__iter__' in dir(name))

4、小结

字面意思:循环更新的一个实实在在的值
内部意思:内部含有“__iter__()”方法的对象,可迭代对象
判断方法:’__iter__’ in dir(对象)
str list tuple dict set range

5、迭代对象优缺点

优点:
    1.存储的数据直接能显示,比较直观
    2.拥有的方法比较多,操作方便
缺点:
    1.占用内存
    2.不能直接通过for循环,不能直接取值(索引和key除外)

for循环在底层做了一个小小的转化,就是先将可迭代对象转化成迭代器,然后在进行取值的。

** 2、迭代器**

1、迭代器的定义

从字面意思来说迭代器,是一个可以迭代取值的工具,器:在这里当做工具比较合适。

    从专业角度来说:迭代器是这样的对象:实现了无参数的__next__方法,返回序列中的下一个元素,如果没有元素了,那么抛出StopIteration异常.python中的迭代器还实现了__iter__方法,因此迭代器也可以迭代。 出自《流畅的python》

    那么对于上面的解释有一些超前,和难以理解,不用过于纠结,我们简单来说:在python中,内部含有’__Iter__‘方法并且含有’__next__‘方法的对象就是迭代器。

2、如何判断该对象是否是迭代器

1
2
with open('heian',mode='w',encoding='utf-8') as f:
    print('__iter__' in dir(f) and '__next__' in dir(f))

3、可迭代对象如何转化成迭代器

1
2
3
4
l1 = [1, 2, 3, 4, 5, 6]
obj = l1.__iter__() 
# 或者 iter(l1)print(obj) 
# <list_iterator object at 0x000002057FE1A3C8>

** 4、 迭代器取值:**

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

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
l1 = [1, 2, 3,]
obj = l1.__iter__()  # 或者 iter(l1)
# print(obj)  # <list_iterator object at 0x000002057FE1A3C8>
ret = obj.__next__()
print(ret)
ret = obj.__next__()
print(ret)
ret = obj.__next__()
print(ret)
ret = obj.__next__()  # StopIteration
print(ret)
# 迭代器利用next取值:一个next取对应的一个值,如果迭代器里面的值取完了,还要next,
# 那么就报StopIteration的错误。

5、while模拟for的内部循环机制

 1
 2
 3
 4
 5
 6
 7
 8
 9
10
l1 = [1, 2, 3, 4, 5, 6]
# 1 将可迭代对象转化成迭代器
obj = iter(l1)
# 2,利用while循环,next进行取值
while 1:
    # 3,利用异常处理终止循环
    try:
        print(next(obj))
    except StopIteration:
        break

6、迭代器的优缺点

优点:
    1.节省内存
    2.惰性机制。 next一次,取一个值,绝不过多取值。​
缺点:
    1.速度慢
    2.不走回头路

1
2
3
4
5
6
7
8
l1 = [1, 2, 3, 4, 5, 6]
obj = iter(l1)

for i in range(2):
    print(next(obj))

for i in range(2):
    print(next(obj))

3、可迭代对象与迭代器对比

可迭代对象:

    是一个私有的方法比较多,操作灵活(比如列表,字典的增删改查,字符串的常用操作方法等),比较直观,但是占用内存,而且不能直接通过循环迭代取值的这么一个数据集。

**    应用**:当你侧重于对于数据可以灵活处理,并且内存空间足够,将数据集设置为可迭代对象是明确的选择。

**    迭代器:**

    是一个非常节省内存,可以记录取值位置,可以直接通过循环+next方法取值,但是不直观,操作方法比较单一的数据集。

    应用:当你的数据量过大,大到足以撑爆你的内存或者你以节省内存为首选因素时,将数据集设置为迭代器是一个不错的选择。(可参考为什么python把文件句柄设置成迭代器)。

未来的你,会感谢今天仍在努力奋斗的你