python函数第5天(day 24)

可迭代的:对象下有__iter__方法的都是可迭代的对象

迭代器:对象.__iter__()得到的结果就是迭代器
迭代器的特性:
    迭代器.__next__() 取下一个值
    
    优点:
        1.提供了一种统一的迭代对象的方式,不依赖于索引
        2.惰性计算
        
    缺点:
        1.无法获取迭代器的长度
        2.一次性的,只能往后取值,不能往前退,不能像索引那样去取得某个位置的值
        
        
生成器:函数内带有yield关键字,那么这个函数执行的结果就是生成器

生成器本质就是迭代器
    def func():
        n=0
        while True:
             yield n
             n+=1
             
    g=func()

    res=next(g)
    res=next(g)

    for i in g:
        pass


总结yield的功能:
    1.相当于把__iter__和__next__方法封装到函数内部
    2.与return比,return只能返回一次,而yield能返回多次
    3.函数暂停已经继续运行的状态是通过yield保存的
    

    
    
    
    
    
yield的表达式形式:
    food=yield
    
def eater(name):
    print('%s start to eat' %name)
    while True:
        food=yield
        print('%s eat %s' %(name,food))
        
e=eater('zhejiangF4')
    

    #e.send与next(e)的区别
        #1.如果函数内yield是表达式形式,那么必须先next(e)
        #2.二者的共同之处是都可以让函数在上次暂停的位置继续运行,不一样的地方在于
            send在触发下一次代码的执行时,会顺便给yield传一个值
    
    


#协程函数的定义?
#协程函数的应用?
定义一个简单的装饰器,完成,协和函数先next这个动作、

def
init(func): def wrapper(*args,**kwargs): res=func(*args,**kwargs) next(res) return res return wrapper @init #eater=init(eater) def eater(name): print('%s start to eat' % name) food_list=[] while True: food = yield food_list print('%s eat %s' % (name, food)) food_list.append(food) e = eater('zhejiangF4') #wrapper('zhengjiangF4') # print(e) # next(e) #e.send(None) print(e.send('123')) print(e.send('123')) print(e.send('123')) print(e.send('123')) print(e.send('123'))
写个函数,源源不断往外,爬网页
from
urllib.request import urlopen def get(): while True: url=yield res=urlopen(url).read() print(res) g=get() next(g) g.send('http://www.python.org')

一个功能,递归,查找,文 件夹下的文件

面向过程,编程思想例题

#grep -rl 'python' C:egon
import os,time
def init(func):
    def wrapper(*args,**kwargs):
        res=func(*args,**kwargs)
        next(res)
        return res
    return wrapper

#找到一个绝对路径,往下一个阶段发一个
@init
def search(target):
    '找到文件的绝对路径'
    while True:
        dir_name=yield #dir_name='C:\egon'
        print('车间search开始生产产品:文件的绝对路径')
        time.sleep(2)
        g = os.walk(dir_name)
        for i in g:
            # print(i)
            for j in i[-1]:
                file_path = '%s\%s' % (i[0], j)
                target.send(file_path)

@init
def opener(target):
    '打开文件,获取文件句柄'
    while True:
        file_path=yield
        print('车间opener开始生产产品:文件句柄')
        time.sleep(2)
        with open(file_path) as f:
            target.send((file_path,f))

@init
def cat(target):
    '读取文件内容'
    while True:
        file_path,f=yield
        print('车间cat开始生产产品:文件的一行内容')
        time.sleep(2)
        for line in f:
            target.send((file_path,line))

@init
def grep(pattern,target):
    '过滤一行内容中有无python'
    while True:
        file_path,line=yield
        print('车间grep开始生产产品:包含python这一行内容的文件路径')
        time.sleep(0.2)
        if pattern in line:
            target.send(file_path)

@init
def printer():
    '打印文件路径'
    while True:
        file_path=yield
        print('车间printer开始生产产品:得到最终的产品')
        time.sleep(2)
        print(file_path)



g=search(opener(cat(grep('python',printer()))))
g.send('C:\egon')
g.send('D:\dir1')
g.send('E:\dir2')


#面向过程的编程思想:流水线式的编程思想,在设计程序时,需要把整个流程设计出来
    #优点:
        #1:体系结构更加清晰
        #2:简化程序的复杂度

    #缺点:
        #1:可扩展性极其的差,所以说面向过程的应用场景是:不需要经常变化的软件,如:linux内核,httpd,git等软件

列表生成式

面试经常会问到

#三元表达式
# name='alex'
# name='egon'
#
# res='SB' if name == 'alex' else 'shuai'
# print(res)



# egg_list=[]
#
# for i in range(100):
#     egg_list.append('egg%s' %i)
# print(egg_list)

#
#先进行for循环,然后,再去判断if子句,然后,再去执行%i把值打印出来
# l=['egg%s' %i for i in range(100) if i > 50]
# print(l)



l=[1,2,3,4]
s='hello'
#把列表l中的每个数字分别与下字符串中的每个字母拼成元组,拼一遍,如(1,'h')(1,'e'),也可以不加if判断,默认全是真
# l1=[(num,s1) for num in l if num > 2 for s1 in s]
# print(l1)

# l1=[]
# for num in l:
#     for s1 in s:
#         t=(num,s1)
#         l1.append(t)
# print(l1)



把下面的,列出文件夹下的文件和列表,进行,列表生成式的改进,列表生成式,本身就是append往里面
# import os
# g=os.walk('C:\egon')
# file_path_list=[]
# for i in g:
#     # print(i)
#     for j in i[-1]:
#         file_path_list.append('%s\%s' %(i[0],j))
#
# print(file_path_list)
#
# g=os.walk('C:\egon')
# l1=['%s\%s' %(i[0],j) for i in g for j in i[-1]]
# print(l1)

模拟数据库查询

#
# l=['egg%s' %i for i in range(100)]
# print(l)

如果用列表生成式,列表是保存在内存中的如果数据太大,直接 死掉,所以这时候就要用到生成器,表达式
也很简单,直接用()括起来就行,然后,再每次next,或者用for来进行迭代,但是要注意,生成器,也即迭代器,
是一次性的,再用,还要再生成
# g=l=('egg%s' %i for i in range(1000000000000000000000000000000000000))
# print(g)
# print(next(g))
# print(next(g))
# for i in g:
#     print(i)



# f=open('a.txt'),a这个文件,每一行两边都有空格,需要把空格 去掉
# l=[]
# for line in f:
#     line=line.strip()
#     l.append(line)
#
# print(l)
# f.seek(0)
# l1=[line.strip() for line in f] 列表生成式是中括号,一次全放内存,不推荐,
# print(l1)
#
# f.seek(0) 此鼠标,要返回首页,很好的解释了,迭代器,是一次性的
# g=(line.strip() for line in f)  生成器表达式,惰性的,用一个取一个,不用担心卡死内存
# print(g)
# print(next(g))



# f=open('a.txt')
# g=(line.strip() for line in f)

# l=list(g)
# print(l)


sum这个函数,()中传的只要是个可迭代的对像,他像for一样,一次next一个,把你传进去的变量,
最后求和
# nums_g=(i for i in range(3))
#
# # print(sum([1,2,3,4]))
# print(sum(nums_g))


下图中的b.txt类似于等,把文件里面的值求和
mac 10000 1
电脑  5000 1

# money_l=[]
# with open('b.txt') as f:
#     for line in f:
#         goods=line.split()
#         res=float(goods[-1])*float(goods[-2])
#         money_l.append(res)
# print(money_l)

#下面是用声明式编程,进行的求和
# f=open('b.txt')
# g=(float(line.split()[-1])*float(line.split()[-2]) for line in f)
#
# print(sum(g))

# with open('b.txt') as f:
#     print(sum((float(line.split()[-1])*float(line.split()[-2]) for line in f)))




# res=[]
# with open('b.txt') as f:
#     for line in f:
#         # print(line)
#         l=line.split()
#         # print(l)
#         d={}
#         d['name']=l[0]
#         d['price']=l[1]
#         d['count']=l[2]
#         res.append(d)

# print(res)



























# with open('b.txt') as f:
#     res=(line.split() for line in f)
#     print(res)
#     dic_g=({'name':i[0],'price':i[1],'count':i[2]} for i in res)
#     print(dic_g)
#     apple_dic=next(dic_g)
#     print(apple_dic['count'])


# apple_dict=next(dic_g)
# print(apple_dict)





#取出单价>10000
with open('b.txt') as f:
    res=(line.split() for line in f)
    # print(res)
    dic_g=({'name':i[0],'price':i[1],'count':i[2]} for i in res if float(i[1]) > 10000)
    print(dic_g)
    print(list(dic_g))
    # for  i in dic_g:
    #     print(i)
原文地址:https://www.cnblogs.com/wanchenxi/p/7414456.html