簡體   English   中英

了解Python中的生成器函數

[英]Understanding generator functions in Python

為什么輸出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嗎?

為什么打印無

在這里,當您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函數中打印“ 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

例如

def hello():
    return "hello"

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

x = gen()

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

默認情況下,函數返回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

你看到區別了嗎? 希望我很清楚。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM