生成器和内置高阶函数

#生成器
#1,列表生成式修改为生成器
li = [i for i in range(100) if i%2==0]
#生成器
g=(i for i in range(100) if i%2==0)
print(g)         #<generator object <genexpr> at 0x1081df9a8>说明其是一个生成器

#2.查看生成器内容的两种方式
#2-1.python3中 g.__next__()方法,但是在python2.x中g.next()方法
#但是在python2.x,python3.x中,next()方法都可以用
print(g.__next__())
print(g.__next__())
print(next(g))
#2-2.for循环
from collections.abc import  Iterable
print(isinstance(g,Iterable))     #True
for i in g:
    print(i)
while True:
    try:
        print(g.__next__())
    except StopIteration:
        print('end')
        break
#__next__()      下一步
#send('xxxx')    给生成器发送'xxxx'
#close()        关闭生成器,再次执行g.__next__()将会报错
#throw()        给生成器发送一个异常(错误)
# g = (i**2 for i in range(5))
# print(g.__next__())
# g.close()
# print(g.__next__())
#
#
# def gen():
#     while True:
#         try:
#             yield 'a'
#         except TypeError:
#             print('type error')
# g = gen()
# print(g.__next__())
# g.throw(TypeError)
# print(g.__next__())

#斐波那契数列生成器的实现
def fib(num):
    a,b,count=0,1,1     #a=0,b=1
    while count <=num:
        yield b     #当在函数中看到yield关键字,那么这个函数调用的返回值是一个生成器;
        a,b =b,a+b      #a=2,b=3
        count +=1
g=fib(10)
for i in g:
    print(i)

#yield 理解
#1.当在函数中看到yield关键字,那么这个函数调用的返回值是一个生成器;
#2,当要执行函数fun时,必须调用g.__next__();
#3.函数执行时,直到遇到yield停止;
#4.想要继续执行,调用g.__next__();从上一次停止的地方继续执行;
def fun():
    a='world'
    print('hello')
    print(1)
    yield 2    #停止
    print(3)
    yield 4
g=fun()
print(g)
for i in g:    #相当于在执行g.__next__()
    print(i)

#生产者消费者模型
import time
import random
def consumer(name):
    print('%s准备买手机'%(name))
    while True:
        kind=yield
        print('%s已经购买了%s的手机。。。'%(name,kind))
def producer(name):
    c1=consumer('Alice')
    c2=consumer('Harry')
    c1.__next__()
    c2.__next__()
    print(c1 is c2)
    print('工厂%s准备生产手机。。。'%(name))
    for kind in ['huawei','xiaomi','vivo']:
        time.sleep(random.random())
        print('%s生产了%s品牌的手机'%(name,kind))
        c1.send(kind)
        c2.send(kind)
producer('Factory')

#协程理解
'''
协程是一种允许在特定位置暂停或恢复的子程序——这一点和生成器相似。
但和生成器不同的是,协程可以控制子程序暂停之后代码的走向,而生
成器仅能被动地将控制权交还给调用者。
练习1:
假设有两个子程序main和printer。printer是一个死循环,等待输入、
加工并输出结果。main作为主程序,不时地向printer发送数据。


加工: [1] text
     [2] text
这应该怎么实现呢?
'''
def printer():
    counter=1
    while True:
        text=yield
        print('%d %s'%(counter,text))
        counter+=1
def main():
    p=printer()
    next(p)
    for i in range(10):
        p.send('A')
        p.send('B')
        p.send('C')
main()

#生成器--迷你聊天机器人
def chat_robot():
    res =''
    while True:
        receive=yield
        if 'age' in receive:
            res = '18'
        elif 'name'in receive:
            res ='小冰'
        elif 'hello' in receive:
            res = 'hello'
        else:
            res ='I dont know'
        printer('Robot:%s'%(res))
def main():
    robot=chat_robot()
    next(robot)
    while True:
        send_date=input('a:')
        if send_date =='q' or send_date=='bye':
            printer('欢迎下次使用')
            break
        robot.send(send_date)
main()


#内置高阶函数
#高阶函数:实参可以是一个函数;返回值也可以是一个函数;
'''
函数定义:
        def 函数名(形参):    def add(a,b):
            函数体
            return 返回值      return 1
调用函数:
        函数名(实参)          add(1,2)
        print(函数名(实参))
'''
#1.map 函数理解
# #在python2中,该函数将function应用到items的每一项并返回结果列表;
#在python3中,创建可产生相同结果的迭代器;
from collections.abc import Iterable
def func(x):
    return x**2
f=map(func,[0,1,2,3,4])
print(isinstance(f,Iterable))
for i  in f:
    print(i)
#1.map函数练习
#需求:用户接收一串数字:'1 3 5 7 8',将该字符中的所有数字转换为整形,并且以表格格式输出;
s = '1 3 5 7 8'
a,b,c,d,e=list(map(int,s.split()))
print(a,e)
print([int(i) for i in s.split()])
#通常可以用[function(x) for x in s]来代替map(function,s)

#reduce:在python2.x中有,在python3.x取消
#reduce在python3.x不是内置高阶函数,而是需要倒入from functools import reduce;
from functools import reduce
def add(x,y):
    return x+y
print(reduce(add,range(5)))
#需求:用户输入数字n:求n的阶乘:5!=1*2*3*4*5
def func(x,y):
    return x*y
print(reduce(func,range(1,6)))    #func(func(1,2),3)


#filter高阶函数:filter(function,iterable)
#1.function:只有一个形参,函数的返回值只能是True或者False;
#在python2中,该函数创建一个由来自iterable的对象组成的列表,其中function的值为真
#在python3中,结果是一个产生此结果的迭代器。如果function是None,则使用相同的函数并且删除所有为假的iterable的元素。
def isodd(num):
    if num%2==0:
        return True
    else:
        return False
print(list(filter(isodd,range(10))))     #只打印为真的值  [0,2,4,6,8]


#sorted:
#排序:由x小到大
# print(sorted([23,54,9,1]))
#排序:由大到小,reverse=True,代表排序后进行反转,reverse关键字参数是一个布尔标志,指定是否按照逆序对生成的列表进行排序
print(sorted([23,54,9,1],reverse=True))      #注意:reversed不能与生成器和迭代器一起使用  [54,23,9,1]

info=[
    ['001','apple',1000,2],
    ['002','xiaomi',10,2000],
    ['003','oppo',200,1900],
    ['004','vivo',300,2100]
]
def sorted_by_count(item):
    return item[2]
print(sorted(info,key=sorted_by_count))
#需要按照商品的价格进行排序,最终显示价格最高的商品名称和数量
def sorted_by_price(item):
    return item[-1]
sorted_by_price_info=sorted(info,key=sorted_by_price)
print(sorted_by_price_info[-1][1],sorted_by_price_info[-1][2])


info={
    '001':{
        'name':'apple',
        'count':1000,
        'price':2
    },
    '002':{
        'name':'xiaomi',
        'count':10,
        'price':2000
    },
    '003':{
        'name':'oppo',
        'count':200,
        'price':1900
    }
}
def dict_sorted_by_count(item):
    return item['count']
print(sorted(info.values(),key=dict_sorted_by_count))

猜你喜欢

转载自blog.csdn.net/xijiao_jiao/article/details/80274929