函数 生成器 列表推导式 生成器表达式 内置函数 匿名函数

day12

一丶生成器

本质:

就是迭代器

生成器产生的方式:

1.生成器函数 👇

2.生成器表达式 👇

3.python内置函数或者模块提供(其实1,3两种本质上差不多,都是通过函数的形式生成,只不过1是自己写的生成器函数,3是python提供的生成器函数而已)

生成器与迭代器的区别:

生成器是我们自己用python代码构建的.迭代器可以使用iter()

 

二丶生成器函数

####只要函数中出现了yiled ,那么就是一个生成器函数.(生成器)
## 一个next 对应一个yield
def func(): #当出现了yiled就是不再是函数了就是生成器函数
   print(111)
   print(111)
   print(111)
   print(111)
   yield 2         # yield的作用是,yield后面的值 给了next取值
   yield 3
   yield 4
   yield 5

ret=func()     # 生成器对象 赋给变量ret
print(ret)     # 生成器对象地址 <generator object func at 0x0000018ACC20EF68>
print(ret.__next__()) # ret执行__next__()方法 取值 2
print(ret.__next__()) # ret执行__next__()方法 取值 3
print(next(ret)) # ret执行__next__()方法 取值 4   next()方法的本质还是__next__()
print(next(ret)) # ret执行__next__()方法 取值 5
print(next(ret)) # 当 生成器对象中没有值可以取的时候就会报错---> StopIteration

 

三丶yiled与return的区别

return:

结束函数,给函数的执行者返回值,多个值通过元组返回,

yiled:

不结束函数 ,(暂停函数) . 对应着给next返回值 , 多个值通过元组返回

# return
def func():

   return 1,2,3,4

print(func())


# yield  
def func():

   yield 1,2,3,4       # yield后面跟一个列表就返回一个列表,返回多个值就是返回一个元组

print(func().__next__())

 

四丶send(了解)

# next只能获取yield生成的值,但是不能传递值。
def gen(name):
   print(f'{name} ready to eat')
   while 1:
       food = yield
       print(f'{name} start to eat {food}')

dog = gen('alex')
next(dog)
next(dog)
next(dog)


# 而使用send这个方法是可以的。
def gen(name):
   print(f'{name} ready to eat')
   while 1:
       food = yield 222
       print(f'{name} start to eat {food}')

dog = gen('alex')
next(dog)  # 第一次必须用next让指针停留在第一个yield后面
# 与next一样,可以获取到yield的值
ret = dog.send('骨头')
print(ret)


def gen(name):
   print(f'{name} ready to eat')
   while 1:
       food = yield
       print(f'{name} start to eat {food}')

dog = gen('alex')
next(dog)
# 还可以给上一个yield发送值
dog.send('骨头')
dog.send('狗粮')
dog.send('香肠')




############# 此处, 先看看, 之后会补充含义


#send和next()区别:
#       相同点:
#           send 和 next()都可以让生成器对应的yield向下执行一次。
#           都可以获取到yield生成的值。

#       不同点:
#           第一次获取yield值只能用next不能用send(可以用send(None))。
#           send可以给上一个yield置传递值。

 

五丶生成器的应用

##生成器应用 ,现在你需要一个服装工厂给你加工2000件衣服,

#加工厂老板,给你准备好了加工衣服的传送带, 夸张一些加工一件衣服1秒.

def func():  #生成器函数, 相当于创建一个加工流水线
   for i in range(1,2001):
       yield print(f'{i}件衣服')   #yield返回数据, 相当于把加工的衣服给来拿衣服的你  
gen_obj = func()  #把生成器给了一个变量, 确保每次来加工时,都是这个流水线(预定)


###需求: 现在你需要200件衣服,老板立马给你制作了200件衣服 ,剩下的1800件还在待加工的状态.
for i in range(200):      # 你拿了200件 ,执行了200次拿的动作
   gen_obj.__next__()    # 在当前的这个流水线(当前的这个生成器),每次拿一件(每次取一个数据)

   
###需求: 现在你需要400件衣服,老板立马从剩余的1800件衣服中又制作了400件衣服给你,现在这个流水线还剩1200
for l in range(400):     # 老板从你预定的流水线继续加工400件
   next(gen_obj)        # 还是在当前的这个流水线(当前的这个生成器),每次拿一件(每次取一个数据)
 

# 总结, 你预定了2000件衣服, 老板没有给你一起直接加工出来,每当你来拿衣服的时候你需要多少个,老板给你咔咔咔把你需要多少个衣服加工出来. 优势:1.对于老板的工厂来说,不占地方, (对于程序来说,不占内存) 2.对加衣服的你也没有影响.(不影响本身程序的调用)



##创建200个生成器函数   --->相当于创建了200流水线
for i in range(200): # 生成200个生成器函数
   print(func().__next__(),type(func()))   # 所以每次打印的都是 1
   

 

六丶yiled与yiled from

##yield 
def func():
    li=[1,2,3,4]
    yield li   # yield 返回一个值   , 若是yield后跟多个值,就以元组的形式返回

ret =func()
print(next(ret))  # 返回一个列表的值(只能得到一个值,next只接一次,不管你是元组 或 列表都是一个值返回)
print(next(ret))  # 报错 StopIteration


##yield from 可以把 后面的可迭代的对象进行拆分,依次给next取值.
def func():
   li=[1,2,3,4]
   yield from li   # yield from 把可迭代对象拆分, 相当于在内部又来了一个生成器. so whtevr

   '''
  #表面现象
    yield 1  
    yield 2  
    yield 3  
    yield 4  
  '''
ret =func()
print(next(ret))  # 1
print(next(ret))  # 2
print(next(ret))  # 3
print(next(ret))  # 4



#### yield 与yield from 对比 ####

# yield : 对应next ,给next 返回值
# yield from 将一个可迭代对象的每一个元素返回给next
# yield from 节省代码 ,提升效率

 

七丶列表推导式,生成器表达式(字典的推导式,集合推导式)

列表推导式:

一行代码构建一个有规律比较复杂的列表。(👇看代码.不废话)

####两种构建方式:
# 1.循环模式: [变量(加工后的变量) for 变量 in iterable]
# 2.筛选模式: [变量(加工后的变量) for 变量 in iterable if 条件]

######循环模式
##需求:循环 100以内的所有的值
#平常做法
li=[]
for i in range(1,101):
   li.append(i)
print(li)

#列表推导式
print([i for i in range(1,101)])



######筛选模式   复杂程度不能超过3级
##案例1:三十以内可以被2整除的数。
print([i for i in range(1,31) if i%2==0])

#案例2: 找到嵌套列表中名字含有两个‘e’的所有名字(有难度)
names = [['Tom', 'Billy', 'Jefferson', 'Andrew', 'Wesley', 'Steven', 'Joe'],
        ['Alice', 'Jill', 'Ana', 'Wendy', 'Jennifer', 'Sherry', 'Eva']]
##普通做法
li=[]
for el in  names:
   for el2 in el:
       if el2.count('e')>=2:
           li.append(el2)
print(li)

##列表推导式
print([name for el in names for name in el if name.count('e')>=2])

     
     
####列表推导式的优缺点
   #优点:简单 快捷
   #缺点:可读性不高,不好拍错
   # 慎用,不用入迷
   

 

生成器表达式:

一行代码构建一个生成器。(👇看代码.不废话)

####两种构建方式:
# 1.循环模式:
# 2.筛选模式:

####循环模式
obj=(i for i in range(10))
print(obj) #<generator object <genexpr> at 0x000001972E9CEF68>

#如何触发生成器(迭代器 )取值? two way
   # 1. next()   , __next__()   逐个取值
   # 2 . for 遍历取值   哪个简单不用多说了吧
   # 3. list()
for  i in obj:
   print(i)

   
   
####筛选模式
obj=(i for i in range(10) if x%2==0)
print(obj)          #<generator object <genexpr> at 0x000001999105FF68>

 

字典的推导式: (创建模式同上👆,一行解决)

####两种构建方式:
# 1.循环模式:
# 2.筛选模式:


li= ['小潘', '第三部','金馆长', '宋老板']

#普通创建字典
dic={}
for k,i in enumerate(li):
   dic[k]=i
print(dic)

#字典推导式
print({k:i for k,i in enumerate(li)})

####

集合推导式:(创建模式同上👆,一行解决)

####两种构建方式:
# 1.循环模式: 
# 2.筛选模式: 

#集合推导式
print({i for i in range(101)})

 

八丶内置函数

什么是内置函数:

由python解释器提供的一些特别的方法,目的提高开发效率

内置函数的数量:

目前:内置函数 68种

👇看代码吧:

# -*- coding: utf-8 -*-
# Author : Ds

#eval() 剥去字符串外衣 执行代码
s1='1+3'
ret=eval(s1)  #去除两端字符,数字相加得到结果
print(ret)

#exce() 也是执行代码流,
s3='''
for i in range(10):
    print(i)
'''
exec(s3)  # 执行for循环

##建议👉: 不要不轻易使用这个两个内置函数. 都是会将代码执行,
       #假如给了一个字符串的病毒,使用这两个方法任意执行.你的电脑都会中毒




#hash() 得到一个哈希值
print(hash(123))   # 数字的哈希值还是数字
print(hash('abc'))
print(hash('abcdkjahfduai'))





#help()查看方法,
print(help(str.upper()))





#callable() 判断是不是一个可调用的对象
# 如果返回 True,object 仍然可能调用失败;但如果返回 False,调用对象 object 绝对不会成功。

def abc():
   pass

a=123
b='123'

print(callable(abc),dir(abc))  # '__call__'
print(callable(a))
print(callable(b))




#bin() oct() hex()
print(bin(100))  # 将十进制转化成二进制。             逢2进一
print(oct(10)) # 将十进制转化成八进制字符串并返回。     逢8进一
print(hex(17)) # 将十进制转化成十六进制字符串并返回。   逢16进一

# 二进制
# 只有 0 1 两个数字, 逢2进一

#八进制
# 0 - 7 , 逢8进一

#十六进制
#0 - 9 , a-f表示 10 -15   逢16进一






#计算除数与被除数的结果,返回一个包含商和余数的元组(a // b, a % b) 分页用到
print(divmod(10, 3))





#保留小数位   四舍五入
print(round(3.123))





# x**y   x的y次幂
print(pow(2,3))




#输入字符寻找其在unicode的位置。
print(ord('a'))
print(ord('中'))




#输入位置数字找出其对应的字符
print(chr(98))  #
print(chr(20104))  # 予




#repr 原形毕露 保留字符串格式
print('不打广告')
print(repr('不打广告'))

msg = '我叫%r' %('不打广告')
print(msg)




#all() 函数用于判断给定的可迭代参数 iterable 中的所有元素是否都为 TRUE
#any() 函数用于判断给定的可迭代参数 iterable 是否全部为 False,
# 0,'',[],{},set(),(),None 都是False

l1 = [1, 'fgdsa', [], {1: 2}]
l2 = [0, '', [], {}]
print(all(l1)) # 判断可迭代对象元素全部都为True,返回True
print(any(l2))  # 判断可迭代对象元素只要有一个True返回True




###print() 打印输入
#sep   设定分隔符
# end 默认是换行可以打印到一行
print(1,2,3,4,sep='|',end=' ')
print(1,2,3,4,sep='|')
# print() 还可以写字符串到文件, file= 文件句柄
f=open('log','a',encoding='utf-8')
print('这是要写入的文件',file=f)
print([1,2,3,4],file=f)       #可以写任意类型的哦!!! 写入就成字符串了
print((1,2,34),file=f)       #可以写任意类型的哦!!!   写入就成字符串了
print({'a':1},file=f)       #可以写任意类型的哦!!!   写入就成字符串了
print(1,file=f)            #可以写任意类型的哦!!!   写入就成字符串了




###list()
#创建列表的集中方式
#1. 直接创建
li=[]
#2. list() 方法
li1=list()
#3. 列表推导表达式
a=[i for i in range(10)]
print(a)  #[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]




###dict()
#字典的创建方式 4 中
#1.直接创建
dic={}
#2. dict()
dic2=dict()
#3. 字典推导式
b={i:1 for i in range(10)}
#4. fromkeys
dic3=dict.fromkeys([1,2,3,4],1)




###获取绝对值 abs()
print(abs(-100))




###sum(iterable,) 求和 必须是数字
print(sum([1,2,3,4]))
print(sum([1,2,3,4],100))
print(sum('1234'))     # 字符串不能求和
print(sum({1:1,2:2,3:3}))  # 字典的键是数字 so 可以相加求和
print(sum((1,2,3,4,5,6)))





####min(*args ,key=) 取最小的值   和 max()用法相同
#1. 普通使用
print(min([1,2,3,4]))                 # 1
print(min((23,10,1,2,3,4)))           # 1
print(min('413'),type(min('413')))    #<class 'str'> 字符串 会被迭代 还是字符串


#2 特殊功能 key=func   ===> key=匿名函数
   #默认情况
       def func(x):   # 此处x得到是迭代对象的每个元素, so 分别是: wuad , aler   , field
           return x[1]  # 返回是以字符串索引为1的字母,比较这个位置的字母的大小.返回最小的
       print(min(['wuad','aler','field'],key=func))  # field
   
   #特殊使用 key=lambda
print(min(['dalao','aordi','xiaocang'],key=lambda x:x[0])) #aordi
   
 
### 👇 min(*args ,key=lambda) 测试
       li = [('艾利克斯', 33, '170cm'), ('杨白', 18, '185cm'), ('武大', 35, '159cm'),]
       #需求: 找年龄最小的元组
           # 分析: 1 找到每个元素 元组,2 把年龄作为返回值 3,打印
       print(min(li,key=lambda x:x[1]))
       #需求: 找年龄最小的元组的身高
      #分析: 1.min(li,key=lambda x:x[1]) 返回一个最小的元组, 2. [2]得到元组后面是取索引位2的值
       print(min(li,key=lambda x:x[1])[2])

####总结:    
#1. 返回值是什么就按照什么比较最小的。
#2. min()会自动的将可迭代对象的每一个元素作为实参传给形参,

# so 继续来测试

##测试1
       dic = {'a':3,'b':2,'c':1}
       #需求: 将dic值最小的键返回。
           #分析: 最小的键是 a
       print(min(dic,key=lambda x:dic[x]))
       #需求: 将dic值最小的值返回。
           #分析: 最小的值的键是 c   ,so 拿键取值
       print(dic[min(dic,key=lambda x:dic[x])])
##测试2
       dic = {'A':['李业', 67],'b': ['怼哥', 95],'c': ['冯垚', 85]}
       #*需求: 将成绩最低的从属于的那个列表返回。
           #分析: 成绩最低 : .需要的是成绩元素为排序的标准,
           # 1 通过键拿到对应的值,值为列表,列表中成绩索引为1 ,根据成绩找到最小so,返回一个键
       print(dic[min(dic,key=lambda x:dic[x][1])])
       
       #*需求: 将成绩最低的分数返回。
           #分析:得到成绩最低的分数 .需要的是成绩元素为排序的标准, 并拿到这个成绩
           # 1.通过键拿到对应的值,值为列表,列表中成绩索引为1根据成绩找到最小 so,返回一个列表,根据列表索引取成绩值
       print(dic[min(dic,key=lambda x:dic[x][1])][1])
     
 ###👆👆👆 如果还是不理解,请指出不理解的点. i can help you to solve



   
   
   
   
   
###reversed() 将一个可迭代的对象进行翻转 ,并返回成一个迭代器(生成器)
s1='不打广告'
print(reversed(s1),type(reversed(s1))) #<reversed object at 0x00000185BD268048> <class 'reversed'>
# 迭代循环取值
s2=reversed(s1)         #可以直接迭代
print(s2.__next__())    #这样可以取值
print(next(s2))         #这样可以取值
for i in s2:            #这样也可以取值
   print(i)



   
   
   
   
###bytes() 将(字符串,或者是数字,但数字就不需要加编码)数据转换成 字节类型
s1='不打广告'
s2='budaguanggao'
s3=1
print(bytes(s1,encoding='utf-8'))
print(bytes(s2,encoding='utf-8'))
print(bytes(1))

#编码
s1 = '不打广告'
# 方法一:
print(s1.encode('utf-8'))
# 方法二:
print(bytes(s1,encoding='utf-8'))

# 解码:
b1 =b'\xe4\xb8\x8d\xe6\x89\x93\xe5\xb9\xbf\xe5\x91\x8a'
# 方法一:
print(b1.decode('utf-8'))
# 方法二:
print(str(b1, encoding='utf-8'))

九丶匿名函数

定义:

没有名字的函数 ,lambda表达式 ,匿名函数只能构建简单的函数

#普通模式, 定义函数
def func(a,b):
   return a+b

#匿名函数构建
#格式--->   lambda关键字 传参   : 返回值
func2=lambda x,y:x+y
print(func2(1,2))

# 写匿名函数:接收一个可切片的数据,返回索引为 0与2的对应的元素(元组形式)。
#匿名函数最常用的就是与内置函数结合使用

#1.
func3=lambda argv : tuple(argv[0:3:2])
print(func3([1,2,3,4]))

#2.
func3=lambda x : (x[0],x[2])
print(func3('你好啊的'))

#3.
func4=lambda x,y : x if x>y else y
print(func4(1,2))

#4.
func4=lambda  *args : max(args)
print(func4(1,2,3,4,5))

posted on 2020-01-11 15:21  向往1  阅读(258)  评论(0)    收藏  举报

导航

……