可迭代对象&迭代器对象&for循环本质
1. 常用内置函数
"""
其中几个方法得到的结果类型是迭代器对象的类型,
所以想要打印出内容,必须用for循环或者其他容器类型包裹,如下例子:
res = zip(l1,name_list)
print(list(res))
res1 = zip(l1,name_list,l2,l3)
for i in res1:
print(i)
"""
# 1. map() # 映射
l = [1,22,333]
print(list(map(lambda x: x+1, l)))
# 循环获取列表中每个元素并传递给匿名函数保存返回值
# map方法详细介绍地址
# 在这里:https://www.cnblogs.com/Joshua-jiaxue/p/15573256.html#_label4
# 2.zip() 拉链
l1 = [1,2,3,4]
name_list = ['jason','jack','joshua','jerry']
l2 = [33,52,53,56,3,2,67]
l3 = [234,435,56,345,763,33]
# 要求将索引相同的元素配对
res = zip(l1,name_list)
print(list(res))
res1 = zip(l1,name_list,l2,l3)
for i in res1:
print(i)
# 3.max(),min()
l4 = [13,21,36,42,58,79,60,3,22]
print(max(l4)) # 79
print(min(l4)) # 3
dic = {
'jason': 2000,
'jack': 4000,
'joshua':1000,
'jerry':3000
}
# 想要获取工资最高的人
print(max(dic)) # joshua
# 由于根据key的字母ASCII的大小排序,所以得不到正确的结果。
# max还支持传入函数
print(max(dic, key=lambda x:dic[x])) # jack
# 4.filter # 过滤
l5 = [12,23,34,45,67,88]
res2 = filter(lambda x: x > 40, l5)
print(list(res2))
# 5.reduce 归总
# 将多个元素变成单个元素
from functools import reduce
l6 = [12,14,22,43,56,66,88,99]
res3 = reduce(lambda x,y: x+y, l6)
print(res3) # 400
res4 = reduce(lambda a,b: a+b, l6, 50)
# 还可以额外添加值
print(res4) # 450
2. 可迭代对象
- 什么叫迭代:
- 即更新换代,每次的更新都必须依赖于上一次的结果
- 主要用于取值。
- 迭代给我们提供了一种,不依赖于索引取值的方式。
- 可迭代对象
- 内置有
__iter__
方法的,都称之为可迭代对象 - 针对双下划线开头,双下划线结尾的方法,最为专业标准的读法为:“双下方法名”,“双下iter”。
- 内置的意思是可以通过
.
方法查看的。
i = 12 f = 1.12 s = 'jack' l = [1,2,23,4] d = {'name':'jack','age':18} t = (1,2,3) se = {11,22,33,44} b = True file = open(r'a.txt','w',encoding='utf8') 我们可以测试下哪些有__iter__方法。 """ 含有__iter__的有 字符串,列表,字典,元组,集合,文件对象 所以上述都可以称为可迭代对象。 """ print(d.__iter__()) # 类似于d.get() print(iter(d)) # 结果与上面一致 print(d.__len__()) print(len(d)) """ 可迭代对象调用了__iter__方法后,会变成迭代器对象。 且 __iter__在调用的时候简便写法iter() 一般情况下所有的双下方法都有一个简写:方法名()加括号。 """
- 内置有
3. 迭代器对象
- 迭代器对象
既含有__iter__方法,又含有__next__方法 - 如何生成迭代器对象
将可迭代对象执行__iter__方法 - 文件对象本身既是可迭代对象,又是迭代器对象
- 迭代器对象无论执行了多少次__iter__方法,结果还是迭代器对象(本身)
i = 12 # 全没有
f = 1.12 #全没有
s = 'jack' # 有iter
l = [1,2,23,4] # 有iter
d = {'name':'jack','age':18} # 有iter
t = (1,2,3) # 有iter
se = {11,22,33,44} # 有iter
b = True #全没有
file = open(r'a.txt','w',encoding='utf8') # 同时有iter和next
res = s.__iter__()
# 此时res有了__next__方法
# print(res.__next__()) # j
# 迭代器对象执行__next__方法其实就是在迭代取值(for循环)
# print(res.__next__()) # j
# print(res.__next__()) # a
# print(res.__next__()) # s
# print(res.__next__()) # o
# print(res.__next__()) # n
# print(res.__next__()) # 再取报错stopiteration
"""易错点!!!!!!"""
print(d.__iter__().__next__()) # username
print(d.__iter__().__next__()) # username
print(d.__iter__().__next__()) # username
print(d.__iter__().__next__()) # username
print(d.__iter__().__next__()) # username
# 每次得到的结果都是username,而不会报错
4. for循环的本质
4.1 for循环内部原理
l1 = [1,2,3,4,5,6,7,8,9,10,11,22,33,44,55,66]
# 循环打印出列表中每个元素,但是不能使用for循环
# 1.先将列表转为迭代器对象
res = l1.__iter__()
while True:
print(next(res))
# 取完值后会报错:StopIteration
"""
for循环内部原理
1.将关键字in后面的数据先调用__iter__方法,转为迭代器对象。
2.循环执行__next__方法
3.取完值后__next__会报错,但是,
for循环会自动捕获该错误,并处理。
res = 数据.__iter__()
while True:
监测代码是否报错
res.__next__()
如果报错则自动处理掉并结束while循环
"""
# 方法一:
# 统计次数,列表元素被打印完毕就停止循环
count = 0
num = len(l1)
while count < num:
print(next(res))
count += 1
"""重点在这里"""
# 方法二:
异常捕获,如下
4.2 异常捕获
-
什么是异常??
代码运行出错,会导致异常,异常发生后,如果没有解决方法,则会导致整个程序结束。 -
异常的三个重要组成部分:
- 异常的追踪信息traceback
翻到错误的最下面,从下往上第一个蓝色字体鼠标左键点击,即可跳转到错误代码所在行。 - 异常的类型
xxxxError - 异常的原因
异常的类型冒号后面的内容。
错误的详细原因很重要。
看完之后可能找到解决的方法。
- 异常的追踪信息traceback
-
错误的种类
- 语法错误
不被允许的,出现了就立刻修改!! - 逻辑错误
可以被允许,出现之后尽快修改即可
修改逻辑错误的过程,其实就是在从头到尾清理思路的过程。
NameError
IndexError
KeyError
ValueError
...等等
- 语法错误
-
捕获异常的基本语法结构
try:
有可能出现错误的代码
except 错误类型 as e:
出错之后对应的处理机制(e是错误的详细信息)
except 错误类型 as e:
出错之后对应的处理机制
except 错误类型 as e:
出错之后对应的处理机制
try:
print(name)
except NameError as e:
print('变量名不存在', e)
# as e 可加可不加,看自己需求。
# 变量名不存在 name 'name' is not defined
# 在我们不知道可能出现的错误类型的时候
# 有万能异常
try:
int('abc')
except Exception: # BaseException
print('啥错都能解决。。。')
"""
异常捕获句式和万能异常
1.有可能会出现错误的代码才需要被监测
2.被监测的代码一定要越少越好
3.异常捕获使用频率越低越好
爬虫程序中会经常用到。
"""
# 下面我们来解决上面的问题
l1 = [1,2,3,4,5,6,7,8,9,10,11,22,33,44,55,66]
# 循环打印出列表中每个元素,但是不能使用for循环
# 1.先将列表转为迭代器对象
res = l1.__iter__()
while True:
try:
print(next(res))
except StopIteration:
print('打印完毕')
break