迭代器相关知识
迭代器
1.可迭代对象
Python中一切皆对象:
数字类型
如:x = 1
字符串类型
name = 'wq'
列表类型
lis = [1,2,3]
元组类型
tup = (1,2,3)
字典类型
dic = {'a':1}
集合类型
s1 = {'a','d'}
函数
def func():
pass
文件
只要拥有__iter__()
方法的对象就是可迭代对象
python中内置字符串(str)、列表(list)、元组(tuple)、字典(dict)、集合(set)、文件(file)都是可迭代对象
2.可迭代对象
只有字符串和列表都是依赖索引取值的,而其他的可迭代对象都是无法依赖索引取值的。因此我们得找到一个方法能让其他的可迭代对象不依赖索引取值。
在找到该方法前,首先我们给出迭代器对象的概念:可迭代的对象执行__iter__
方法得到的返回值。并且可迭代对象会有一个__next__
方法。
s = 'hello'
iter_s = s.__iter__()
while True:
try:
print(iter_s.__next__())
except:
break
#try...except...为异常处理模块
迭代器对象:执行可迭代对象的__iter__
方法,拿到的返回值就是迭代器对象。
特点:
-
内置
__next__
方法,执行该方法会拿到迭代器对象中的一个值 -
内置有
__iter__
方法,执行该方法会拿到迭代器本身 -
文件本身就是迭代器对象
缺点:
- 取值麻烦,只能一个一个取,并且只能往后取,值取了就没了
- 无法使用len()方法获取长度
三元表达式
特点:条件成立时的返回值 if 条件 else 条件不成立时的返回值
print(f"x if x > y else y: {x if x > y else y}")
列表推导式
print(F"[i for i in range(10)]: {[i for i in range(10)]}")
字典生成式
print({i: i**2 for i in range(10)})
zip()方法
通过解压缩函数生成一个字典
keys = ['name', 'age', 'gender'] values = ['nick', 19, 'male'] res = zip(keys, values) print(F"zip(keys,values): {zip(keys,values)}") info_dict = {k: v for k, v in res} print(f"info_dict: {info_dict}")
生成器
yield的英文单词意思是生产,在函数中但凡出现yield关键字,再调用函数,就不会继续执行函数体代码,而是会返回一个值
def func():
print('from func 1')
yield 'a'
print('from func 2')
yield 'b'
g = func()
print(F"g.__iter__ == g: {g.__iter__() == g}")
res1 = g.__next__()
print(f"res1: {res1}")
res2 = next(g)
print(f"res2: {res2}")
#
g.__iter__ == g: True
from func 1
res1: a
from func 2
res2: b
def func():
print('from func 1')
yield 'a'
print('from func 2')
yield 'b'
g = func()
for i in g:
print(i)
print(f"list(func()): {list(func())}")
#
from func 1
a
from func 2
b
from func 1
from func 2
list(func()): ['a', 'b']
递归
函数的嵌套调用是:函数嵌套函数。函数的递归调用:它是一种特殊的嵌套调用,但是它在调用一个函数的过程中,又直接或间接地调用了它自身。
递归必须要有两个明确的阶段:
- 递推:一层一层递归调用下去,进入下一层递归的问题规模都将会减小
- 回溯:递归必须要有一个明确的结束条件,在满足该条件开始一层一层回溯。
递归的精髓在于通过不断地重复逼近一个最终的结果。
匿名函数
匿名函数,他没有绑定名字,使用一次即被收回,加括号既可以运行。
res = (lambda x, y: x+y)(1, 2)
print(res)
匿名函数通常与内置函数连用
匿名函数通常与max()、sorted()、filter()、sorted()方法联用。
1.如果我们想从上述字典中取出薪资最高的人,我们可以使用max()方法,但是max()默认比较的是字典的key。
-
首先将可迭代对象变成迭代器对象
-
res=next(迭代器对象),将res当做参数传给key指定的函数,然后将该函数的返回值当做判断依据
salary_dict = { 'nick': 3000, 'jason': 100000, 'tank': 5000, 'sean': 2000 } print(f"max(salary_dict): {max(salary_dict)}") def func(k): return salary_dict[k] print(f"max(salary_dict, key=func()): {max(salary_dict, key=func)}") # 'nick', v1 = func('nick') # 'jason', v2 = func('jason') # 'tank', v3 = func('tank') # 'sean', v4 = func('sean') print( f"max(salary_dict, key=lambda name: salary_dict[name]): {max(salary_dict, key=lambda name: salary_dict[name])}")
2.如果我们想对上述字典中的人,按照薪资从大到小排序,可以使用sorted()方法。
sorted()工作原理:
-
首先将可迭代对象变成迭代器对象
-
res=next(迭代器对象),将res当做参数传给第一个参数指定的函数,然后将该函数的返回值当做判断依据。
salary_dict = { 'nick': 3000, 'jason': 100000, 'tank': 5000, 'sean': 2000 } print( f"sorted(salary_dict, key=lambda name: salary_dict[name]): {sorted(salary_dict, key=lambda name: salary_dict[name])}")
3.如果我们想对一个列表中的某个人名做处理,可以使用map()方法。
map()工作原理:
-
首先将可迭代对象变成迭代器对象
-
res=next(迭代器对象),将res当做参数传给第一个参数指定的函数,然后将该函数的返回值作为map()方法的结果之一。
name_list = ['jason', 'tank', 'sean'] res = map(lambda name: f"{name} sb", name_list) print(f"list(res): {list(res)}") # list(res): ['jason sb', 'tank sb', 'sean sb']
4.如果我们想筛选除名字中含有'sb'的名字,我们可以使用filter()方法。
filter()工作原理:
-
首先将可迭代对象变成迭代器对象
-
res=next(迭代器对象),将res当做参数传给第一个参数指定的函数,然后filter会判断函数的返回值的真假,如果为真则留下
name_list = ['nick', 'jason sb', 'tank sb', 'sean sb'] filter_res = filter(lambda name: name.endswith('sb'), name_list) print(f"list(filter_res): {list(filter_res)}") # list(filter_res): ['jason sb', 'tank sb', 'sean sb']
内置函数
1.bytes()
解码字符
res = bytes('你好', encoding='utf8')
print(res)
2.chr() / ord()
chr()参考ASCII码表将数字转成对应字符;ord()将字符转换成对应的数字。
3.divmod()
分栏
4.enumerate
枚举:带有索引的迭代
l = ['a', 'b', 'c']
for i in enumerate(l):
print(i)
#
(0, 'a')
(1, 'b')
(2, 'c')
5.eval()
把字符串翻译成数据类型。
lis = '[1,2,3]'
lis_eval = eval(lis)
print(lis_eval)
6.hash()
是否可哈希
面向过程编程思想
优点:复杂的问题流程化,进而简单化。
生产汽水瓶的流水线,没办法生产特斯拉。流水线下一个阶段的输入与上一个阶段的输出是有关联的。因此他的扩展性极差。
缺点:扩展性差。
分层实现功能
- 用户功能层:实现用户具体的功能。
- 接口层:连接数据处理层和用户功能层。
- 数据处理层:处理数据后把结果交给接口层。
分层实现功能的好处:当我们需要实现web端和app端的软件,我们只要把数据处理层和接口层写好,然后实现不同的用户功能层即可,web端使用web端的用户功能层,app端使用app端的用户功能层,但是接口层和数据处理层是通用的。