python之迭代器生成器和内置函数,匿名函数
今天学习了迭代器生成器以及内置函数和匿名函数,说实话有些懵圈,有些难度了。
一、迭代器和生成器
1、如何从列表、字典中取值的:
index索引
for循环
凡是可以使用for循环取值的都是可迭代的
(1)可迭代协议:内部含有__iter__方法的都是可迭代的
(2)迭代器协议:内部含有__iter__方法和__next__方法的都是迭代器
什么是可迭代的:内部含有__iter__方法的都是可迭代的
什么是迭代器:迭代器=iter(可迭代的),自带一个__next__方法
可迭代最大的优势:节省内存
py2中的range不管range多少,会生成一个列表,这个列表将用来储存所有值
py3中的range不管range多少,都不会实际的生成任何一个值
判断是否可迭代或是否为迭代器:
from collections import Iterable,Iterator
print(range(10000))
print(isinstance(range(10000),Iterable))是否为可迭代
print(isinstance(range(10000),Iterator))是否为迭代器
迭代器的优势:
节省内存
去一个值就能进行接下来的计算,而不需要等到所有的值都 计算出来才开始接下来的运算--速度快
迭代器的特性:惰性运算
2、生成器(Generator)
自己写的迭代器就是一个生成器
两种自己写生成器(迭代器)的机制:生成器函数,生成器表达式
(1)生成器函数:
def cloth_g(num):
for i in range(num):
yield 'cloth%s'%i
g = cloth_g(100)
print(next(g))
print(next(g))
凡是带有yield的函数就是一个生成器函数
yiled记录当前所在的位置,等待下一次next来触发函数的状态
生成器函数的调用不会触发代码的执行,而是会返回一个生成器(迭代器)
想要生成器函数执行,需要用next。
使用生成器监听文件输入的例子
import time
def listen_file():
with open('file') as f:
while True:
line = f.readline()
if line.strip():
yield line.strip()
time.sleep(0.1)
g = listen_file()
for line in g:
print(line)
send关键字:在执行next的过程中传递一个参数给生成器函数的内部
想生成器中传递值,有一个激活过程,第一次必须使用next触发这个生成器
如何从生成器中取值
(1)next随时都可以停止,最后一次会报错
(2)for循环从头到尾遍历一次,不遇到break、return不会停止
(3)list tuple数据类型的强转,会把所有的数据都加载到内存,浪费内存
生成器函数是我们python程序员实现迭代的一中手段
主要特征是在函数中含有yield
调用一个生成器函数不会执行这个函数中的代码,只会获得一个生成器(迭代器)
只有从生成器中取值的时候,才会执行函数内部的代码,且每获取一个数据才执行得到这个数据代码
获取数据的方式包括next、send循环,数据类型的强制转化
yield返回值的简便方法,如果本身就是循环一个可迭代的,且要把可迭代数据中的每一个元素都返回,可以用yield from
使用send的时候,在生成器创造出来之后需要进行预激,这一步可以使用装饰器完成
生成器特点:节省内存,惰性运算
生成器用来解决内存问题和程序功能之间的解耦
3、生成器表达式,在庞大数据量的时候使用生成器表达式
list = (out_exp_res for out_exp in input_list if out_exp == 2)
列表推导式,排序的时候用
list = [out_exp_res for out_exp in input_list if out_exp == 2]
out_exp_res:列表生成元素表达式,可以是有返回值的函数
for out_exp in input_list:迭代input_list将out_exp传入out_exp_res表达式中
if out_exp == 2:根据条件过滤哪些值可以返回
(1)一个生成器只能取值一次
(2)生成器在不找它要值的时候始终不执行
(3)当他执行的时候,要以执行时候的所有变量值为准
二、内置函数和匿名函数
1、内置函数:
callable(o),o是参数,看这个变量是不是可调用。o是函数名返回Ture
dir()查看一个变量锁拥有的所有名字
bin():二进制,oct()八进制,hex()十六进制
abs():计算绝对值
divmod():求商和余数(商余函数)
enumerate():显示元素的索引
eval():提取执行
pow():pow(2,3,3) #(2**3)%3对2的三次方取余
reversed():将列表倒序输出
.sort():按升序排列
round():默认取整,小数精确,四舍五入
__import__:通过字符串导模块
id(o) o是参数,返回一个变量的内存地址
hash(o) o是参数,返回一个可hash变量的哈希值,不可hash的变量被hash之后会报错。
sum():求和运算
min():计算最小值
max():计算最大值
print(ord('a'))输入字符找该字符编码的位置 a-z 97+26
print(chr(97))输入位置数字找出其对应的字符 A-Z 65+26
ascii:是ascii码中的返回该值,不是就返回/u
format('打印元素','<20'):<左对齐,>右对齐,^居中对齐
repr():返回一个对象的string形式(原形毕露)
enumerate:枚举接收两个参数:一个容器类型,一个序号起始值
all():可迭代对象中,全部是Ture才是Ture
any():可迭代对象中,有一个Ture就是Ture
for i in zip():函数用于将可迭代的对象作为参数,将对象中对应的元素大包成一个个元组,然后返回这些元组组成的列表,列表长度与最短的相同
print(self, *args, sep=' ', end='\n',file=None,flush=T/F)
file:默认输出到屏幕,如果设置为文件句柄,输出到文件
sep:打印多个值之间的分隔符,默认为空格
end:每一次打印的结尾,默认为换行符
flush:立即把内容输出到流文件,不作缓存
hash哈希
(1)对可hash的数据类型进行hash之后会得到一个数字
(2)在一次程序的执行过程中,兑相同的可哈希变量哈希之后结果永远相同
(3)在一次程序的执行过程中对不相同的可哈希变量哈希之后结果几乎总是不相同的
(4)hash字典底层的存储和set集合的去重机制都相关
filter():过滤元素
map:def func(num):
return num ** 2
for i in map(func,range(10)):print(i)
sorted(l,key=...):排序
2、匿名函数
lambda:匿名函数关键字:函数名 = lambda 参数:返回值
calc<函数名> = lambda<定义匿名函数关键字> n<参数>:n**n<返回值>
print(calc(10))
三、递归调用:
1、递归调用在调用一个函数的过程中,直接或间接又调用该函数本身,称之为递归调用
递归必备两个阶段:1、递推 2、回溯
2、递归调用必须要有一个明确的结束条件
3、每次进入更深一层递归时,问题规模相比上次递归都应有所减少
4、递归效率不高
修改递归最大深度
import sys
print(sys.setrecursionlimit(1000))
四、二分法
l = [18,22,26,30,32,35,41,42,43,55,56,66,67,69,72,76,82,83,88]
def func(l,num):
mid = len(l) //2 #中间截取
if num > l[mid]: #判断所传数字是否大于mid
func(l[(mid)+1:],num) #大于从中间往后找
elif num < l[mid]: #判断所传数字是否小于mid
func(l[0:(mid)],num) #大于从中间往前找
else:print('find it')
func(l,66)