了解Python中的生成器函数

时间:2017-06-30 07:20:30

标签: python generator

为何输出None

def hello():
    print("hello")

def gen():
    yield hello();
    yield hello();
    yield hello();

for x in gen():
    print(x)

结果是:

hello 
None 
hello 
None 
hello 
None

为什么没有印刷? 不是你好* 3?

2 个答案:

答案 0 :(得分:3)

为什么打印无

当你print()但没有return任何内容时,python会在结尾自动添加return

让我们看一个使用dis

的例子
import dis

def hello():
  print('hello')

dis.dis(hello)

输出:

      0 LOAD_CONST               1 ('hello')
      3 PRINT_ITEM          
      4 PRINT_NEWLINE       
      5 LOAD_CONST               0 (None)
      8 RETURN_VALUE    

现在,当您返回显式值时,请立即查看:

import dis

def hello():
  return 'hello'

dis.dis(hello)

输出:

    0 LOAD_CONST               1 ('hello')
    3 RETURN_VALUE  

请参阅,LOAD_CONST 0 (None)第二次没有被调用。因此,加载的第一个值是return。

您应该采取哪些措施来改善代码

这样做,如果你只需要打印"你好"在hello函数内。

def hello():
    print("hello")

def gen():
    yield hello()
    yield hello()
    yield hello()

for x in gen():
    x

或者,使用返回值,在这种情况下,您需要返回而不是打印。

def hello():
    return "hello"
    ^ Here I return rather than print hello

def gen():
    yield hello()
    yield hello()
    yield hello()

for x in gen():
    print(x)

但是调用多个yield是很奇怪的,最好做一个循环以避免StopIteration

e.g

def hello():
    return "hello"

def gen():
    while True:
        yield hello()

x = gen()

for i in range(3):
  print(x.next())

答案 1 :(得分:0)

通过默认函数返回None类型。

def hello():
    pass

def gen():
    yield hello();
    yield hello();
    yield hello();

for x in gen():
    print(x)

输出:

None
None
None

什么是发电机?

生成器和函数之间的主要区别在于您可以动态获取值。并且在生成器生成一个值yield之后。并且返回下一个值,旧值不是存储在内存中

迭代生成器

def hello():
    for x in range(3):
        yield x*x


for i in hello():
    print(i)

输出:

0
1
4

现在使用next()

def hello():
    for x in range(3):
        yield x*x

gen = hello()

for i in range(3):
    print(next(gen))

输出:

0
1
4

到目前为止一切顺利。对? gen = hello()此处gen成为生成器对象。

迭代列表

my_list = [x*x for x in range(3)]
for i in my_list:
    print(i)

输出:

0
1
4

输出相同?是同样的输出。但唯一不同的是,我可以使用my_list迭代次数我想要的任何次数,

my_list = [x*x for x in range(3)]
for i in my_list:
    print(i)
print("\n")
for i in my_list:
    print(i)

输出:

0
1
4

0
1
4

但是如果我在耗尽时尝试使用生成器

def hello():
    for x in range(3):
        yield x*x

gen = hello()

for i in range(3):
    print(next(gen))
next(gen)

输出

0
1
4
Traceback (most recent call last):
  File "/home/mr/sadas.py", line 12, in <module>
    print(next(gen))
StopIteration

如何克服这个?再次创建一个新的生成器对象并使用。

def hello():
    for x in range(3):
        yield x*x

gen = hello()

for i in range(3):
    print(next(gen))

gen = hello()

for i in range(3):
    print(next(gen))

输出:

0
1
4
0
1
4

你看到了区别吗?希望我很清楚。