Menu Close

Python教程中的Yield:Generator , Yield , return

yield是什么?

python中的yield关键字的工作方式类似于带有唯一的return

区别在于,它不返回值,而是将生成器对象返回给调用方。

当调用一个函数并且执行线程在该函数中找到yield关键字时,该函数执行将在该行本身处停止,并将生成器对象返回给调用方。

在此Python教程中,您将学习:

  • yield是?
  • 语法
  • 什么是Python中的generators?
  • 普通函数和generator函数。
  • 如何从generators读取值?
  • generators使用
  • 示例:Fibonacci 序列 generators 和 yield
  • 示例:yield调用函数
  • 何时在Python中使用Yield而不是Return
  • yield与return

语法

yield expression

描述

Python yield返回一个generator对象。generator是特殊的函数,必须对其进行迭代才能获取值。

yield关键字将给定的表达式转换为生成器函数,该函数返回一个生成器对象。要获得对象的值,必须对其进行迭代以读取赋予产量的值。

示例:yield 方法

这是一个简单的产量示例。函数testyield()具有一个yield关键字,其字符串为“ Welcome to icfedu Python ”。调用该函数时,将输出输出,并提供一个生成器对象而不是实际值。

def testyield():
  yield "Welcome to icfedu Python"
output = testyield()
print(output)  

Output:

<generator object testyield at 0x000001FC8157F660>

给定的输出是一个生成器对象,具有我们给定的yield值。

但是我们没有得到必须给出的信息以产生输出!

要打印给出yield的消息,将必须迭代生成器对象,如下例所示:

def testyield():
  yield "Welcome to icfedu Python"

output = testyield()
for i in output:
    print(i)

Output

Welcome to icfedu Python

什么是Python generator?

生成器是返回可迭代生成器对象的函数。一次仅从生成器对象中获取一个值,而不是一起获取完整列表,因此要获取实际值,可以使用next()或list()方法使用for循环。

使用生成器功能

您可以使用生成器函数和生成器表达式来创建生成器。

生成器函数类似于普通函数,而不是具有返回值,而是具有yield关键字。

要创建生成器函数,您将必须添加yield关键字。以下示例显示了如何创建生成器函数。

def generator():
    yield "H"
    yield "E"
    yield "L"
    yield "L"
    yield "O"

test = generator()
for i in test:
    print(i)

Output:

H
E
L
L
O

普通函数与generators函数之间的差异。

让我们了解生成器与普通函数有何不同。

有2个函数normal_test()和generator_test()。

假定这两个函数都返回字符串“ Hello World”。normal_test()使用return,generator_test()使用yield。

# Normal function
def normal_test():
    return "Hello World"
	
#Generator function
def generator_test():
	yield "Hello World"
print(normal_test()) #call to normal function
print(generator_test()) # call to generator function

Output:

Hello World
<generator object generator_test at 0x00000012F2F5BA20>

输出显示,当您调用普通函数normal_test()时,它将返回Hello World字符串。对于具有yield关键字的生成器函数,它将返回<generator object generator_test at 0x00000012F2F5BA20>而不是字符串。

这是生成器和普通函数之间的主要区别。现在要从生成器对象获取值,我们需要在循环内使用该对象,或者使用next()方法或使用list()。

print(next(generator_test()))  # will output Hello World

添加到普通函数与生成器函数的另一个不同之处是,当您调用普通函数时,执行将在返回并返回值给调用者时开始和停止。因此,当执行开始时,您无法停止其间的正常功能,只有遇到return关键字时,它才会停止。

但是对于生成器函数,一旦获得第一个yield就开始执行,它将停止执行并返回生成器对象。您可以使用生成器对象获取值,也可以根据需要暂停和恢复。

如何从生成器读取值?

您可以使用list(),for循环和next()方法从生成器对象读取值。

使用:list()

列表是一个可迭代的对象,其元素放在方括号内。在生成器对象上使用list()将提供生成器持有的所有值。

def even_numbers(n):
    for x in range(n):
       if (x%2==0): 
           yield x       
num = even_numbers(10)
print(list(num))

Output:

[0, 2, 4, 6, 8]

使用:for-in

在示例中,有一个函数定义了even_numbers(),它将为您提供所定义n的所有偶数。调用函数even_numbers()将返回一个生成器对象,该对象在for循环内使用。

Example:

def even_numbers(n):
    for x in range(n):
       if (x%2==0): 
           yield x       
num = even_numbers(10)
for i in num:
    print(i)

Output:

0
2
4
6
8

使用next()

next()方法将为您提供列表,数组或对象中的下一项。一旦列表为空,并且如果调用next(),它将通过stopIteration信号返回错误。来自next()的此错误表示列表中没有其他项目。

def even_numbers(n):
    for x in range(n):
       if (x%2==0): 
           yield x       
num = even_numbers(10)
print(next(num))
print(next(num))
print(next(num))
print(next(num))
print(next(num))
print(next(num))

Output:

0
2
4
6
8
Traceback (most recent call last):
  File "main.py", line 11, in <module>
    print(next(num))
StopIteration

generator是一次性使用的

如果是generator,则只能使用一次。如果您尝试再次使用它们,它将为空。

例如:

def even_numbers(n):
    for x in range(n):
       if (x%2==0): 
           yield x       
num = even_numbers(10)
for i in num:
    print(i)

print("\n")
print("Calling the generator again: ", list(num))

Output:

0
2
4
6
8
Calling the generator again:  []

如果您希望再次使用输出,则必须再次调用该函数。

示例:Fibonacci数列的generator和yield

以下示例显示了如何在Python中使用生成器和yield。该示例将生成斐波那契数列。

def getFibonnaciSeries(num):
    c1, c2 = 0, 1
    count = 0
    while count < num:
        yield c1
        c3 = c1 + c2
        c1 = c2
        c2 = c3
        count += 1
fin = getFibonnaciSeries(7)
print(fin)
for i in fin:
    print(i)

Output:

<generator object getFibonnaciSeries at 0x0000020C43D3F660>
0
1
1
2
3
5
8

示例:调用yield函数

在此示例中,将看到如何使用yield调用函数。

下面的示例具有一个称为test()的函数,该函数返回给定数字的平方。还有另一个名为getSquare()的函数,该函数使用带有yield关键字的test()。输出给出给定数字范围的平方值。

def test(n):
    return n*n

def getSquare(n):
    for i in range(n):
        yield test(i)

sq = getSquare(10)
for i in sq:
    print(i)

Output:

0
1
4
9
16
25
36
49
64
81

何时在Python中使用Yield而不是Return

Python3 Yield关键字将生成器返回给调用者,并且仅在迭代生成器时才开始执行代码。

函数的返回是函数执行的结束,并且将单个值返回给调用方。

在这种情况下,您应该使用Yield而不是Return

  • 数据量较大时,使用yield而不是return
  • 当您需要更快地执行大型数据集时,良率是最佳选择
  • 要向调用函数返回大量值时,请使用yield
  • 产量是产生大数据或无限数据的有效方法。

yield与return

区别

yield return
Yield将生成器对象返回给调用者,并且仅在迭代生成器时才开始执行代码。 函数的返回是函数执行的结束,并且将单个值返回给调用方。
当函数被调用并且遇到yield关键字时,函数执行将停止。它将生成器对象返回给调用者。仅当执行生成器对象时,函数执行才会开始。 调用该函数时,执行开始,如果存在return关键字,则将值返回给调用方。函数内部的返回标志着函数执行的结束。
yeild表达式 return表达式
使用yield关键字时不使用内存。 将为返回的值分配内存。
如果由于不使用内存而不得不处理庞大的数据量,则非常有用。 方便用于非常小的数据。
如果yield关键字用于大数据量,则性能会更好。 如果数据量太大会影响性能,则会使用大量内存。
在大数据量的情况下,执行时间更快。 使用的执行时间更多,因为如果您的数据量很大,则需要进行额外的处理,这对于较小的数据量将是很好的。

概括:

  • python中的yield关键字的工作方式类似于return,唯一的区别在于,它不返回值,而是将生成器函数返回给调用者。
  • 生成器是一种特殊的迭代器,一旦使用,将不再可用。这些值不存储在内存中,仅在调用时可用。
  • 可以使用for-in,list()和next()方法读取来自生成器的值。
  • yield和return之间的主要区别在于yield将生成器函数返回给调用者,而return将单个值返回给调用者。
  • Yield不将任何值存储在内存中,并且好处是,当数据大小很大时,这将很有用,因为这些值都不存储在内存中。
  • 如果使用yield关键字进行比较以返回较大的数据大小,则性能会更好。
Posted in Python

发表评论

相关链接