python---迭代器, for循环底层原理

目录

何为迭代?

可迭代对象

迭代器对象

迭代器的优缺点

优点

缺点

for循环底层原理

迭代取值与索引取值对比


何为迭代?

迭代器即用来迭代取值的工具,而迭代是重复反馈过程的活动,其目的通常是为了逼近所需的目标或结果,每一次对过程的重复称为一次“迭代”,而每一次迭代得到的结果会作为下一次迭代的初始值,单纯的重复并不是迭代.

迭代其实就是更新换代, 每一次结果都是基于上一次的结果, eg: 游戏版本更新, 每次更新都是基于上一版本的迭代.

单纯的循环并不是迭代

 import time
 while True:
     print(123)
     time.sleep(0.1)

迭代

# 属于迭代
n = 1
while True:
    print(n)
    n += 1

迭代取值

# 迭代取值
l1 = [11, 22, 33, 44, 55]
n = 0
while n < len(l1):
    print(l1[n])
    n += 1

可迭代对象

通过索引的方式进行迭代取值,实现简单,但仅适用于序列类型:字符串,列表,元组。对于没有索引的字典、集合等非序列类型,必须找到一种不依赖索引来进行迭代取值的方式,这就用到了迭代器。

要想了解迭代器为何物,必须事先搞清楚一个很重要的概念:可迭代对象(Iterable)。从语法形式上讲,内置有__iter__方法的对象都是可迭代对象字符串、列表、元组、字典、集合、打开的文件都是可迭代对象:


 大白话理解就是数据可以通过点的方式点出来__iter__
 
 

迭代器对象

迭代器对象   即可迭代对象调用__iter__方法之后生成的结果就是迭代器对象迭代器对象的特征
   为含有__iter__方法和__next__方法.  迭代器对象能够极大的节省存储空间

    调用__next__方法即可进行迭代器对象取值 如果取完了则会直接报错!!!

  ps:开辟了一种不需要索引取值的方式(for循环底层依据的就是迭代器对象)
  '''有了迭代器对象才出现了针对字典和集合的迭代取值操作'''


迭代器对象补充说明
1.有很多双下方法其实都有简便写法 但不是全部
  """
  __方法名__  等价  方法名()
      最为常见的两个是
          __iter__    iter()
          __next__    next()

  """

2.有一些可迭代对象本身也是迭代器对象>>>:文件对象
3.可迭代对象调用一次__iter__方法编程迭代器对象  如果继续调用 结果还是迭代器对象本身.

# s = 'yietong'
# print(s.__iter__())   # 
# print(iter(s))  # 

res = s.__iter__()
res1 = s.__iter__().__iter__().__iter__()
print(res, res1)
#  

4.迭代取值的要求
  print(s.__iter__().__next__())      每次先产生一个新的迭代器对象然后取值

s = 'yietong'
res = s.__iter__()
print(res.__iter__().__next__())
print(res.__iter__().__next__())
print(res.__iter__().__next__())
print(res.__iter__().__next__())
print(res.__iter__().__next__())
print(res.__iter__().__next__())
print(res.__iter__().__next__())

# y
# i
# e
# t
# o
# n
# g

迭代器的优缺点

基于索引的迭代取值,所有迭代的状态都保存在了索引中,而基于迭代器实现迭代的方式不再需要索引,所有迭代的状态就保存在迭代器中,然而这种处理方式优点与缺点并存:

优点

1、为序列和非序列类型提供了一种统一的迭代取值方式。

2、惰性计算:迭代器对象表示的是一个数据流,可以只在需要时才去调用__next__来计算出一个值,就迭代器本身来说,同一时刻在内存中只有一个值,因而可以存放无限大的数据流,而对于其他容器类型,如列表,需要把所有的元素都存放于内存中,受内存大小的限制,可以存放的值的个数是有限的。

缺点

1、除非取尽,否则无法获取迭代器的长度

2、只能取下一个值,不能回到开始,更像是‘一次性的’,迭代器产生后的唯一目标就是重复执行next方法直到值取尽,否则就会停留在某个位置,等待下一次调用next;若是要再次迭代同个对象,你只能重新调用iter方法去创建一个新的迭代器对象,如果有两个或者多个循环使用同一个迭代器,必然只会有一个循环能取到值。

for循环底层原理


    for 变量名 in 可迭代对象:
        循环体代码

1.会将in后面的数据调用__iter__()变成迭代器对象
    为什么文件对象也可以for循环 因为文件本身就是迭代器对象 再次调用不变

2.针对产生的迭代器对象依次调用__next__()方法迭代取值

3.当值取完之后 会自动处理报错并退出循环.

需求:不依赖于for循环 完成对列表元素的取值

l1 = [11,22,33,45,66,77]
res = l1.__iter__()
while True:
    print(res.__next__())

'''
11
22
33
45
66
77
Traceback (most recent call last):
  File "C:/me/JetBrains/pythonProject/迭代器/迭代器.py", line 185, in 
    print(res.__next__())
StopIteration
'''

for循环结合异常处理

res = 可迭代对象.__iter__()
while True:
  try:
      print(res.__next__)
  except StopIteration as e:
    break

迭代取值与索引取值对比

1.索引取值
   优势:可以反复获取相同的元素 并且没有固定的方向
  劣势:只能支持有序的容器类型 无序的无法取值兼容性没有迭代取值高
 
2.迭代取值
    优势:兼容所有的容器类型
  劣势:取值的顺序永远都是从左往右 并且无法重复获取 取完就完了
  # 真正底层的迭代取值后续可能很少用 一般都是for循环代替
"""
迭代器里面的东西是固定的 每取一个就会少一个 取完就空了
"""

python---迭代器, for循环底层原理_第1张图片

你可能感兴趣的:(python基础,python,开发语言)