文章 96
评论 76
浏览 89991
Python之生成器

Python之生成器

虽然生成器对象的使用方法与迭代器对象类似,但是内部原理是不同的
构建迭代器时,不是把所有元素一次性加载到内存,而是一种延迟计算的方式返回元素。
生成器就是一特殊迭代器,它不会把所有内容放在内存里,每次调用 next()函数时,返回的都是本次计算出来的那个元素,用完之后立刻销毁。

  • 迭代器
    可迭代协议 —— 含有 iter 方法的都是可迭代的
    迭代器协议 —— 含有 next 和 iter 的都是迭代器
#生成器函数
def generator():
    print(1)
    return 'a'
ret = generator()
print(ret)
#只要含有yield关键字的函数都是生成器函数
#yield不能和return共用且需要写在函数内
def generator():
    print(1)
    yield 'a'
#生成器函数 : 执行之后会得到一个生成器作为返回值
ret = generator()
print(ret)
print(ret.__next__())

通过学习,知道了生成器表达式比列表推导式更不占用内存。

例如:
列表推导式:

#列表推导式
print([i*i for i in range(10)]) 

#生成器表达式
g = (i for i in range(10))
print(g)
for i in  g:
    print(i)

列表推导式和生成器表达式不同:

  • 括号不一样
  • 返回的值不一样 === 几乎不占用内存(生成器表达式)

实战

  1. 处理文件,用户指定要查找的文件和内容,将文件中包含要查找内容的每一行都输出到屏幕
def check_file(filename,app):
    with open(filename,encoding='utf-8') as f:   #句柄 : handler,文件操作符,文件句柄
        for i in f:
            if app in i:
                yield i

g = check_file('pwd','ding')
for i in g:
    print(i.strip())
  1. 写生成器,从文件中读取内容,在每一次读取到的内容之前加上‘***’之后再返回给用户。
def check_file(filename):
    with open(filename,encoding='utf-8') as f:   #句柄 : handler,文件操作符,文件句柄
        for i in f:
            yield '***'+i

for i in check_file('pwd'):
    print(i.strip())

生成器函数进阶拆解

def add(n,i):
    return n+i
def test():
    for i in range(4):
        yield i
g = test()
for n in [1,10,5]:
    g = (add(n,i) for i in g)
print(list(g))

此函数拆解步骤:

def add(n,i):
    return n+i
def test():
    for i in range(4):
        yield i
g = test()
# for n in [1,10,5]:
#     g = (add(n,i) for i in g)
# print(list(g))
n = 1
g = (add(n,i) for i in test())
n = 10
g = (add(n,i) for i in (add(n,i) for i in test()))
n = 5
g = (add(n,i) for i in (add(n,i) for i in (add(n,i) for i in test())))

print(list(g))

将如下进行拆解,g=test()

def add(n,i):
    return n+i
def test():
    for i in range(4):
        yield i
g = test()
# for n in [1,10,5]:
#     g = (add(n,i) for i in g)
# print(list(g))
n = 1
g = (add(n,i) for i in g)
n = 10
g = (add(n,i) for i in (add(n,i) for i in g))
n = 5
g = (add(n,i) for i in (add(n,i) for i in (add(n,i) for i in g)))

print(list(g))
  • 细化:
n = 5
g = (add(n,i) for i in (add(n,i) for i in (add(n,i) for i in test())))

n = 5
g = (add(n,i) for i in (add(n,i) for i in (add(n,i) for i in (0,1,2,3))))

n = 5
g = (add(n,i) for i in (add(n,i) for i in (5,6,7,8)))

n = 5
g = (add(n,i) for i in (10,11,12,13))

④ 最终

n = 5
g = (15,16,17,18)

到头来 我们记住的 不是敌人的攻击 而是朋友的沉默 ---马丁·路德·金

                    

记录精彩的坎坷人生,经营属于自己的世界!