美文网首页
Python生成器

Python生成器

作者: 马本不想再等了 | 来源:发表于2019-02-14 00:09 被阅读0次

1 生成器概念

生成器是一个特殊的迭代器(迭代器的抽象层级更高)
所以,生成器拥有迭代器的特性:1.惰性计算,节省内存。2.更够记录状态,并通过next()函数,访问下一个状态。3.具备可迭代特性。

2 生成器的的创建

(1)使用生成器表达式,示例代码如下:

# l = [i for i in range(1, 1000) if i % 2 ==0]
# 直接生成一个列表
l = (i for i in range(1, 1000) if i % 2 ==0)
# 直接生成一个生成器
print(next(l))
print(next(l))
print(l.__next__())
>>> 2
>>> 4
>>> 6

(2)使用生成器函数

函数中包含yield语句,这个函数执行结果就是“生成器”,示例代码如下:
yield,可以去阻断当前的函数运行,使用next()函数或next()方法,都会让函数继续执行,执行到下一个yield语句并把yield后的值当做状态值返回,函数到此处暂停。
特别说明:不使用next()或next()方法,函数不会执行,一行都不会执行,只会返回一个生成器。

def test():
  print("xxx")
  yield 1
  print("a")
  yield 2
  print("b")
  yield 3
  print("c")
  yield 4
  print("d")

g = test()
print(g) 
print(next(g))
print(next(g))
print(next(g))
>>> <generator object test at 0x000000002134d5>
>>> xxx
>>> 1
>>> a
>>> 2
>>> b
>>> 3

当生成器内的yield语句运行完之后,再一直使用next()或next()方法,就会报错StopIteration

也可以使用for in 来遍历,这种方法可以把最后一个yield下面的语句也运行出来。

def test():
  print("xxx")
  yield 1
  print("a")
  yield 2
  print("b")
  yield 3
  print("c")
g = test()

for i in g:
    print(i)
>>> xxx
>>> 1
>>> a
>>> 2
>>> b
>>> 3
>>> c

3 send()方法

(1)send()方法有一个参数,指的是上一次被挂起的yield语句返回值
(2)相比于.next(),send()可以额外的给yield传值
(3)注意第一次使用,t.send(None)
next()方法只是执行,不会传入值

def test():
    print("xxx")
    res1 = yield 1
    print(res1)
    res2 = yield 2
    print(res2)
g = test()

print(g.__next__())
print(g.__next__())
>>> xxx
>>> 1
>>> None # res1的值为None
>>> 2

send()方法给res1传入了值ooo,send()执行的位置在yield2处,但是它传入的值给到了上一次被挂起的yield1处。

def test():
    print("xxx")
    res1 = yield 1
    print(res1)
    res2 = yield 2
    print(res2)
g = test()

print(g.__next__())
print(g.send("ooo"))
>>> xxx
>>> 1
>>> ooo  # res1的值为ooo
>>> 2

直接执行send()传值操作会报错,因为它只给上一个yield挂起位置传值。

def test():
    print("xxx")
    res1 = yield 1
    print(res1)
    res2 = yield 2
    print(res2)
g = test()

print(g.send("ooo"))
>>> TypeError: can't send non-None value to a just-started generator

g.send(None) <=> g.next(),我们可以使用send(None),运行第一个yield,到第二个再使用send()传值就可以了。

def test():
    print("xxx")
    res1 = yield 1
    print(res1)
    res2 = yield 2
    print(res2)
g = test()

print(g.send(None))
print(g.send("ooo"))
>>> xxx
>>> 1
>>> ooo
>>> 2

4 close()方法关闭生成器

使用close()方法可以直接关闭生成器,再次调用生成器,会报错StopIteration

def test():
    yield 1
    print("a")
    yield 2
    print("b")
    yield 3
    print("c")
g = test()

print(g.__next__())
print(g.__next__())
g.close()
print(g.__next__())
>>> 1
>>> a
>>> 2
>>> StopIteration

5 注意事项:

如果碰到return,生成器会直接终止,抛出StopIteration异常提示

def test():
    yield 1
    print("a")
    yield 2
    print("b")
    return 10
    yield 3
    print("c")
g = test()

print(g.__next__())
print(g.__next__())
print(g.__next__())
>>> 1
>>> a
>>> 2
>>> 3
>>> StopIteration:10

生成器只会遍历一次,再次遍历需要重新创建,比如再次使用g = test()

相关文章

网友评论

      本文标题:Python生成器

      本文链接:https://www.haomeiwen.com/subject/kmejeqtx.html