可迭代对象
什么是迭代?
迭代的言外之意就是更新换代,每次更新都会依赖于上一次的结果
什么又是可迭代对象呢?
就是内置方法中有__iter__()的都可以被称为可迭代对象。
__name__:这种的属性
__iter__:这种是方法
"""
__iter__()
双下划线开头的方法我们是第一次遇到,他是一种特殊的方法
像双下划线开头的方法在面相对象里面最常见
用法跟普通方法都是一样的
"""
"""
是可迭代对象的有:
字符串、列表、元组、字典、集合等
整型、浮点型、布尔值都不是
ff = open('a.txt', 'w', encoding='utf8')
文件对象也是可迭代对象,因为内置的有__iter__()方法
"""
可迭代对象调用__iter__()方法就变成了'''迭代器对象'''
l = [1, 2, 3, 4, 5, 6, 7, 8]
res = l.__iter__()
print(res) # <list_iterator object at 0x0000026677F8D390>
"""
一般情况下,双下滑先开头的方法都有一个与之对于的简化方法 名字()
"""
如: __iter__ >>>>> iter()
__len__ >>>>> len()
__next__ >>>>> next()
迭代器对象
迭代器对象:迭代器
什么是迭代器对象?
既内置了__iter__()方法,又内置了__next__方法就是迭代器对象
'''文件本身就具有__iter__和__next__方法'''
即是可迭代对象又是迭代器对象
# 到底都有哪些数据类型是迭代器对象
str、list、dict、tuple、set、文件等
# 迭代器对象有什么用呢
"""
迭代器其实是一种不依赖于索引取值的方式!
可迭代对象多次调用__iter__()方法后还是迭代器对象,所以你只需要调用一次即可。
"""
Eg:
l = [1, 2, 3, 4, 5, 6, 7, 8]
# 索引取值
print(l[0]) # 1
print(l[1]) # 2
# 迭代取值
res = iter(l)
print(next(res)) # 1
print(next(res)) # 2
Eg2:
d = {'username': 'ly', 'age': 18}
res = iter(d)
print(next(res)) # username
print(next(res)) # age
### 注意:
d = {'username': 'ly', 'age': 18}
print(iter(d).__next__()) # username
print(iter(d).__next__()) # username
当取完一次后,又重新迭代了,就会取到重复得zhi
Eg3:
"""易错题"""
ll = [1, 2, 3, 4]
res = ll.__iter__()
print(res.__next__()) # 1
print(res.__next__()) # 2
print(res.__next__()) # 3
print(res.__next__()) # 4
print(res.__next__()) # StopIteration 当数据被取值完的时候,如果在次next会直接报错
for循环原理
Eg:
l = [1,2,3,4,5,6,7,8]
# 循环打印出列表中的每一个元素,但是不能使用for循环,必须要使用__next__()取值
res = iter(l)
print(next(res))
l = [1, 2, 3, 4, 5, 6, 7, 8]
res = iter(l)
count = 0
while count < 8:
print(next(res))
count += 1
for循环又称为迭代循环,in后可以跟任意可迭代对象,上述while循环可以简写为
for i in l:
print(i)
for循环的原理:
1. 先把关键字in后面的可迭代对象先调用__iter__()
2. while循环,next()取值
3. for的内部当出现异常的时候,做了捕捉处理:StopIteration的错误,break
异常捕获
1. 什么是异常?
异常就是错误发生的信号,如果不对此信号做正确处理,那么之后的程序都不能正常运行了
2. 异常的分类
1. Traceback
是异常所在的位置,一般情况我们直接可以定位到异常发生的位置所在处
2. XXXError
错误的类型
3. XXXError后面的详细信息
重要,一般情况我们直接看错误发生的详细信息都可以定位原因
4. 异常都有哪些类型
1. 语法错误
# 坚决不允许的,容易解决,借助于pycharm工具就可以很容易的定位到
2. 逻辑错误
# 是允许被出现的,但是,我们在写代码的时候,尽量的避免逻辑错误的发生
3. XXXError
错误的类型
# print(name) # NameError
# l = [1,2,3,4]
# print(l[5]) # IndexError
# d = {'a':1}
# print(d['b']) # KeyError
# 1/0 # ZeroDivisionError
4、如何解决这些异常:关键字(try except)
"""
语法结构:
try
被监测的代码:一般是可能会发生的错误
except 错误类型1 as e
print(e)
except 错误类型2 as e
print(e)
except 错误类型3 as e
print(e)
except 错误类型4 as e
print(e)
"""
try:
print(name)
except NameError as a:
print(a) # name 'name' is not defined
Exception:万能捕捉异常关键字
try:
print(name)
d = {'aa': 'bbb'}
print(d['aaaa'])
except Exception as a:
print(a) # name 'name' is not defined
# finally
try:
print(name)
except NameError as a:
print(a) # name 'name' is not defined
else:
print('看一下else什么时候走的?')
finally:
print('看一下finally什么时候走?')
"""
没有异常的时候else会走,有异常的时候else不会走
finally是不管有没有异常都会走
"""
try:
pass
except NameError:
pass
#################
try:
pass
finally:
pass
#################
try:
pass
except :
pass
else:
pass
# 这里面你只需要记住try和else不能单独使用,会报错
# assert: 断言,我断定你一定是正确的、成功的、可行的等
s = 1+2
# 在这一行我居断定s必须是2,如果不是2直接拦截,
assert s == 2
# assert 条件 条件必须成立,如果不成立,代码在这一行直接中断
print(123)
迭代取值的优缺点
1、优点:
1、为序列和非序列类型提供了一种统一的迭代取值方式。
2、惰性计算:迭代器对象表示的是一个数据流,可以只在需要时才去调用next来计算出一个值,就迭代器本身来说,同一时刻在内存中只有一个值,因而可以存放无限大的数据流,而对于其他容器类型,如列表,需要把所有的元素都存放于内存中,受内存大小的限制,可以存放的值的个数是有限的。
2、缺点:
1、除非取尽,否则无法获取迭代器的长度
2、只能取下一个值,不能回到开始,更像是‘一次性的’,迭代器产生后的唯一目标就是重复执行next方法直到值取尽,否则就会停留在某个位置,等待下一次调用next;若是要再次迭代同个对象,你只能重新调用iter方法去创建一个新的迭代器对象,如果有两个或者多个循环使用同一个迭代器,必然只会有一个循环能取到值。
迭代取值和索引取值 的对比
迭代取值
1. 不依赖于索引取值
2. 只能从做往右依次取值,不能重复取值
索引取值
1. 必须依赖于索引取值
2. 可以重复取值
l[0]
3. 必须是容器类型
标签:__,迭代,Python,res,基础,iter,next,print
From: https://www.cnblogs.com/chao0308/p/17451976.html