day03.23迭代器

迭代器

什么是迭代:

迭代其实就是指更新换代,但是每一次迭代的过程都需要依赖于上一次的结果。

迭代器:

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

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])
'''
11
22
33
44
55
'''
n += 1
复制代码

可迭代对象:

从python的语法形式上讲,内置有__iter__方法(双下iter方法)的对象都是可迭代对象。

尝试调用__iter__方法,可以查看数据是否为可迭代对象。例如字符串、列表、元组、字典、集合、打开的文件都是可迭代对象。

复制代码
i = 11  # 整型不是
f = 11.11  # 浮点型不是
s = 'jason'  # 字符是
l = [1,2,3,4]  # 列表是
d = {'name':'jason','age':18}  # 字典是
t = (1,2,3,4)  # 元组是
se = {1,2,3,4,5}  # 集合是
b = True  # 布尔值不是
f = open()  # 文件是
def index():pass  # 普通函数不是
复制代码

可迭代对象提供了除了索引取值外的另一种取值方法,相较于索引取值来说,二者各有优劣。

迭代器对象:

  1. 可迭代对象调用__iter__方法之后生成的结果就是迭代器对象。
  2. 迭代器是Python提供的一种统一的、不依赖于索引的迭代取值方式,只要存在多个“值”,无论序列类型还是非序列类型都可以按照迭代器的方式取值。
  3. 迭代器对象是内置有__iter__和__next__方法的对象,如果对迭代器对象执行__iter__方法,得到的仍然是迭代器本身;而如果对迭代器执行__next__方法,得到的就是迭代器下一次计算的值。
  4. 迭代器对象能够极大的节省内存空间。
  5. 迭代器对象取值时直接调用__next__方法即可,但是需要注意迭代器取值结束之后继续取值会报错!!!(字典和集合for循环取值的底层都是使用的迭代器取值)

ps:

  • 许多的双下方法都有简写方式,二者是等价的。例如__iter__等价于iter();__next__等价于next()。
s = 'jason'
print(s.__iter__())
print(iter(s))
print(s.__len__())
print(len(s))
  • note:有些迭代器对象本身也是可迭代对象,比如文件!!!
  • 可迭代对象调用一次__iter__方法迭代变成器对象;如果继续调用__iter__方法,其结果还是迭代器对象本身。
s = 'jason'
res = s.__iter__()    # 此时已经是迭代器对象
res1 = s.__iter__().__iter__().__iter__()    # 对迭代器对象进行双下iter方法后,还是迭代器对象本身
print(res, res1)  # <str_iterator object at 0x10762bdd8>      <str_iterator object at 0x107636dd8>

eg:迭代取值要点,注意区别迭代对象和迭代器对象。

复制代码
s = 'jason'
print(s.__iter__().__next__())  # j 每次先产生一个新的迭代器对象然后取值
print(s.__iter__().__next__())  # j 每次先产生一个新的迭代器对象然后取值
print(s.__iter__().__next__())  # j 每次先产生一个新的迭代器对象然后取值
print(s.__iter__().__next__())  # j 每次先产生一个新的迭代器对象然后取值

res = s.__iter__()  # 已经变成迭代器对象了
print(res.__iter__().__next__())  # j  之后再调用还是自身
print(res.__iter__().__next__())  # a
print(res.__iter__().__next__())  # s
print(res.__iter__().__next__())  # o
复制代码

for循环的内部原理和本质

for循环的底层原理就是迭代器,其内部结构如下:

for  变量名   in   可迭代对象:

        循环体代码
  1. 会将in后面的数据调用__iter__()变成迭代器对象
  2. 针对产生的迭代器对象依次调用__next__()方法迭代取值
  3. 当值取完之后,会自动处理报错并退出循环

eg:

# 不依赖于for循环 完成对列表元素的取值
l1 = [11, 22, 33, 44, 55, 66, 77, 88]
res = l1.__iter__()    # 迭代对象运用__iter__方法变为迭代器对象
n = 0
while n < len(l1):
    print(res.__next__())    # 对迭代器对象进行迭代取值
    n += 1
复制代码
# 利用while与异常捕获 实现for循环的功能
info = {'name': 'jason', 'age': 18, 'pwd': 123}
# 1.先转换成迭代器对象
# res  = info.__iter__()
res = iter(info)
# 2.迭代取值
while True:
    # print(res.__next__())
    try:
        print(next(res))
    except StopIteration as e:
        # 结束while循环
        break
复制代码

迭代取值和索引取值的优劣

迭代取值:

优点:

  • 兼容所有的容器类型,为序列和非序列类型提供了一种统一的迭代取值方式。
  • 迭代器可以很大程度的节省内存空间。惰性计算:迭代器对象表示的是一个数据流,可以只在需要时才去调用__next__来计算出一个值,就迭代器本身来说,同一时刻在内存中只有一个值,因而可以存放无限大的数据流,而对于其他容器类型,如列表,需要把所有的元素都存放于内存中,受内存大小的限制,可以存放的值的个数是有限的。

缺点:

  • 取值的顺序永远都是从左往右 并且无法重复获取,取完就结束了
  • 除非取尽,否则无法获取迭代器的长度

索引取值:

优点:可以反复获取相同的元素,并且没有固定的方向,可以一次取到任意想取的元素

缺点:只能支持有序的容器类型,无序的无法取值,其兼容性没有迭代取值高

异常处理

异常又称为bug,即代码运行出错之后就是异常,异常会导致程序立刻停止 。

异常信息的组成部分:

复制代码
Traceback (most recent call last):
File "/Users/jiboyuan/PycharmProjects/day16/05 异常处理.py", line 3, in <module>
    name
NameError: name 'name' is not defined
'''
line关键字所在的那一行,用来提示是那一行代码出错
NameError提示代码的错误的类型
name 'name' is not defined就是指描述代码错误的具体原因

'''
复制代码

 

异常的分类:

异常分为语法结构异常和逻辑异常两种。其中语法异常时低级错误,是不被允许存在的错误。

异常的类型:

eg:异常的类型有很多种

print(name)  # NameError     名字错误
l1 = [11, 22, 33]
print(l1[100])  # IndexError 索引错误
d = {'name': 'jason'}
print(d['age'])  # KeyError  键错误
int('jason')  # ValueError   值错误

 

异常处理的操作:

通过代码来处理跳过异常错误,使整个代码能够继续运行下去。

基本的语法结构:

try:
# 可能会出错的代码
except '错误的类型1' as e:  # e指代的就是错误的提示信息
# 针对性的处理措施
except '错误的类型2' as e:  # e指代的就是错误的提示信息
# 针对性的处理措施
except '错误的类型3' as e:  # e指代的就是错误的提示信息
# 针对性的处理措施

万能的语法结构:

try:
    '可能会出错的代码'
except Exception as e:
    '统一的处理措施'

异常处理的原则:

  1. 被检测的代码越少越好
  2. 能尽量少用就尽量少用

 

posted @   *sunflower*  阅读(76)  评论(0编辑  收藏  举报
(评论功能已被禁用)
相关博文:
阅读排行:
· DeepSeek 开源周回顾「GitHub 热点速览」
· 物流快递公司核心技术能力-地址解析分单基础技术分享
· .NET 10首个预览版发布:重大改进与新特性概览!
· AI与.NET技术实操系列(二):开始使用ML.NET
· 单线程的Redis速度为什么快?
点击右上角即可分享
微信分享提示