day14 生成函数的进阶

1、上节回顾:python

一、可迭代对象:惰性运算          拥有__iter__方法面试

二、迭代器:                              拥有__iter__和__next__方法app

三、生成器:惰性运算,开发者自定义   本质:迭代器 因此拥有__iter__和__next__方法ide

     惰性运算:不取值就不计算  且每个值只能被取一次,取完为止函数

     生成器的优势:延迟计算,一次返回一个结果,也就是说,它不会一次生成全部的结果,这对于大数据处理很是有用大数据

生成器------迭代器:节省内存spa

1)生成器函数:3d

   带有yield 关键字code

   执行函数以后的返回值是生成器,函数内的代码并不会真正执行对象

   想让生成器吐出数据,须要使用next 方法,send, for循环

2、新内容

一、生成器的调用例子 取用:cloth

def cloth():
    for i in range(100):
        yield "衣服%s"%i
g=cloth()
# 方法一
# for i in g:
#     print(i)
# 方法二
for i in range(100):
    print(g.__next__())
cloth

 

二、监听文件末尾追加的例子

调用生成器并不执行,当取用的时候才会执行def下面的内容(Windows系统的时候才可使用)

def tail():
    f=open("你好.bak","r",encoding="utf-8")
    f.seek(0,2)
    while True:
        line=f.readline()
        if line:
            yield line
        import time
        time.sleep(0.1)
g=tail()
for i in g:
    print(i.strip())
生成器(监听文件)

三、send  和next 的范围是同样的

     (1)从哪个yield开始接着执行,就把一个值传给了那个yield

    (2)send 不能用在第一个触发生成器,触发生成器第一个必须是__next__()

     (3)生成器函数中有多少个yield就必须有多少个next+send

def func():
    print("*"*10)
    a=yield 5
    print(a)
    yield  10
g=func()
num=g.__next__()
print(num)
num2=g.send("alex")
print(num2)
# **********
# 5
# alex
# 10
send 例子
def averager():
    total=0.0
    count=0
    average=None
    while True:
        term=yield  average
        total+=term
        count+=1
        average=total/count
g_avg=averager()
g_avg.__next__()
print(g_avg.send(10))
print(g_avg.send(20))
print(g_avg.send(30))
# 10.0
# 15.0
# 20.0
利用 send(银行七日化利息)

四、补充:python3 以后有的这个功能:yield from a

def func():
    a="AB"
    b="CD"
    yield from a
    #for i in a:yield i
    yield from b
    #for i in b:yield i
g_func=func()
for i in g_func:
    print(i)
yield from 的使用

五、触发执行的方式

(1)生成器.__next__()

 (2)生成器.send()        

      send(None)==__next__().  

      send在next的基础上传一个值到生成器函数的内部

      send 操做不能用在生成器使用的第一次

      以上两个执行几回拿几个数据,可能会遇到取完报错

(3)for循环   每次取一个,取完为止。for循环不会报错

六、总结:

    生成器函数:生成一个生成器的函数

    生成器的本质:参数迭代器

    生成器函数的特色:(1)带有yield 关键字 (2)且调用以后,函数内的代码不执行

 触发执行的方式:(1)next  (2)send  (3)for 循环

3、各类推导式

 一、列表推导式:

y=[1,2,3,4,5,6,7]
# 方法一
# x=[]
# for i in y:
#     x.append(i**2)
# print(x)
# 方法二
x=[i**2 for i in y]
print(x)
# [1, 4, 9, 16, 25, 36, 49]
列表推导式1
# x=[]
# for i in range(100):
#     x.append(i/2)
# print(x)
x=[i/2 for i in range(100)]
print(x)
列表推导式2

二、生成器表达式 (生成器表达式+for循环节省内存 推荐使用)

#列表推导式
y=[1,2,3,4,5,6]
x=[i**2 for i in y]  #[  ]
print(x)
#生成器表达式
y=[1,2,3,4,5,6]
g=(i**2 for i in y)  #(  )
print(g)
for i in g:
    print(i)
列表推导式和生成器表达式
l=["鸡蛋%s"%i for i in range(10)]
print(l)
lmuji=("鸡蛋%s"%i for i in range(10))
for egg in lmuji :
    print(egg)
鸡蛋和母鸡的理论

 三、补充:

并非全部的均可以转换

g.__next__()==next(g )
g.__iter__()==inter(g)

四、30之内能被3整除的数的平方 列表推导式的例子

# 30之内能被3整除的数的平方
# x=[i**2 for i in range(30) if i%3==0]
# print(x)
def square(x):
    return  x**2
x=[square(i) for i in range(30) if i%3==0]
print(x)
30之内能被3整除的数的平方

五、字典推导式

dic={"a":10,"b":34}
dic_fre={dic[k]:k for k in dic}
print(dic_fre)
#{10: 'a', 34: 'b'}   key value 对换
key value 对换
mcase={"a":10,"b":34,"A":7,"Z":3}
mcase_frequency={k.lower():mcase.get(k.lower(),0)+mcase.get(k.upper(),0)for k in mcase}
print(mcase_frequency)
#{'a': 17, 'b': 34, 'z': 3}
字典中大小写相加

六、集合的推导式 去重

squared={x**2 for x in [1,-1,2]}
print(squared)
#set([1,4])
集合的去重

 

 

面试题:

相关文章
相关标签/搜索