简体   繁体   English

了解Python中的生成器函数

[英]Understanding generator functions in Python

Why it outputs None ? 为什么输出None

def hello():
    print("hello")

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

for x in gen():
    print(x)

result is: 结果是:

hello 
None 
hello 
None 
hello 
None

why None is printed?? 为什么不打印? not hello * 3 ? 不是* 3吗?

Why it prints None : 为什么打印无

Here when you print() but doesnt return anything, python will add a return automatically at the end. 在这里,当您print()但不return任何内容时,python会在末尾自动添加一个return

Let's see an example using dis 我们来看一个使用dis的例子

import dis

def hello():
  print('hello')

dis.dis(hello)

output: 输出:

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

Let's see now when you return an explicit values: 现在让我们看一下您返回的显式值:

import dis

def hello():
  return 'hello'

dis.dis(hello)

output: 输出:

    0 LOAD_CONST               1 ('hello')
    3 RETURN_VALUE  

See, the LOAD_CONST 0 (None) was not called the second times. 请参见,第二次未调用LOAD_CONST 0 (None) Therefore, the first value being loaded was return. 因此,要加载的第一个值是return。

What you should do to improve your code : 您应该做什么来改善您的代码

Do this, if you just need to print "hello" inside the hello function. 如果只需要在hello函数中打印“ hello”,请执行此操作。

def hello():
    print("hello")

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

for x in gen():
    x

OR, use return value, in that case you need to return instead of printing. 或者,使用返回值,在这种情况下,您需要返回而不是打印。

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)

But it is weird to call several yield , better do a loop to avoid a StopIteration 但是调用多个yield很奇怪,最好做一个循环以避免StopIteration

eg 例如

def hello():
    return "hello"

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

x = gen()

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

By default functions return None type. 默认情况下,函数返回None类型。

def hello():
    pass

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

for x in gen():
    print(x)

Output: 输出:

None
None
None

What are generators? 什么是发电机?

The main difference between generators and functions is that you can obtain values on the fly. 生成器和函数之间的主要区别在于,您可以即时获取值。 And after one value is yield 'ed by the generator. 和一个值后yield由发电机“编 and next value is returned the old one is not stored in the memory . 返回下一个值,旧值不存储在内存中

Iterating over a generator 在生成器上迭代

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


for i in hello():
    print(i)

Output: 输出:

0
1
4

Now using next() 现在使用next()

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

gen = hello()

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

Output: 输出:

0
1
4

So far so good. 到现在为止还挺好。 Right? 对? gen = hello() here gen becomes a generator object. gen = hello()在这里, gen成为生成器对象。

Iterating over a list 遍历列表

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

Output: 输出:

0
1
4

Same output? 输出相同吗? Yes same output. 是相同的输出。 But only difference here is that I can use the my_list iterable any number of times I want, 但唯一的区别是我可以任意多次使用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)

Output: 输出:

0
1
4

0
1
4

However if I try to use the Generator when it is exhausted. 但是,如果在电量耗尽时尝试使用发电机

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

gen = hello()

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

Output 输出量

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

How to overcome this? 如何克服呢? Create a new generator object again and use. 再次创建一个新的生成器对象并使用。

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))

Output: 输出:

0
1
4
0
1
4

You see the difference? 你看到区别了吗? Hope I was clear. 希望我很清楚。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM