【问题标题】:What does yield do in python 2.7? [duplicate]yield 在 python 2.7 中做了什么? [复制]
【发布时间】:2012-04-09 20:44:49
【问题描述】:

可能重复:
The Python yield keyword explained

好的,我的问题可能措辞很糟糕,但这就是我的情况。

我正在尝试理解 Python 2.7 中的这行代码:

yield (padding_zeros + number_string).encode("ascii")

在这行代码中,padding_zeros 是一个可变数字“0”的字符串,number_string 是一个字符串形式的数字,可以是 0 到 10000 之间的任意数字。

我非常有信心 .encode("ascii") 只是将 yield 的输出转换为 ascii。

我完全不知道yield (padding_zeros + number_string) 做了什么。

我知道它会启动一个生成器,但我花了很多时间在线搜索并阅读语法,但我仍然无法弄清楚生成器实际上 做了什么。这是我第一次看python,这并没有帮助(我的最终目标是将这段代码转换为C#)。

那么,基本上,有人可以向我解释一下这行代码的作用吗?它只是将两个字符串加在一起还是做一些更复杂的事情?

对于进一步的上下文,这是该行代码出现的块:

for current_length in range(4, max_length + 1):
    for i in range(0, pow(10, current_length)):
        number_string = str(i)
        padding_zeros = "0" * (current_length - len(number_string))
        yield (padding_zeros + number_string).encode("ascii")

max_length 就像它听起来的样子 - 一个表示某物的最大长度的数字)

提前感谢所有答案(即使他们告诉我不要成为这样的菜鸟):)

编辑:非常感谢您的回答 - 尽管我只能选择一个作为最佳答案,但他们都非常有帮助。还要感谢 cmets - 正如他们中的一些人指出的那样,What does the "yield" keyword do in Python? 是一个非常好的关于产量、生成器和迭代的一般指南,即使我没有找到它对我的具体情况的答案:)

【问题讨论】:

  • 这是 Python 2 还是 Python 3?
  • 嗨乔治,你的问题在这里得到了很好的回答,我觉得:stackoverflow.com/questions/231767/…
  • Python 2.7 抱歉,应该在问题中明确说明。
  • 简短回答您的问题:您错误地解析了语句。 yield 产生表达式 (padding_zeros + number_string).encode("ascii"),正如您所猜到的,它是一个 ascii 字符串。知道 yield 可能会有所帮助,就像 python 2 中的 print 一样,它的参数不需要括号。

标签: python string generator python-2.7 yield


【解决方案1】:

yield 就像在生成器中返回。

在执行yield 时,生成器函数停止执行,并返回值。不同之处在于,当再次调用生成器时,会在 yield 语句处重新开始执行,并继续执行,直到遇到另一个 yield,或者引发(未处理的)异常,或者遇到 returnreturn 或异常将终止生成器。

生成器的意义在于可以将其调用为x = next(generator)x = generator.next(),并且每次都会从生成器内部的yield 中接收值。生成器也是可迭代的,因此它们可以用作循环的源:for x in generator: print x

与 C# 中一样,. 运算符在出现在运算符左侧的对象上调用其右侧命名的方法。因此,(padding_zeros + number_string).encode("ascii") 根据(padding_zeros + number_string) 的结果调用encode

encode的含义见这里:http://docs.python.org/library/stdtypes.html#str.encode

语言参考(假设您使用的是 python 2):http://docs.python.org/reference/index.html

【讨论】:

    【解决方案2】:

    生成器是一种状态机,它在 python 中实现了迭代器接口或 __iter__。 它会在“yield”之后等待,直到你调用 next() 。

    试试这个:

    def my_gen():
        for current_length in range(4, max_length + 1):
            for i in range(0, pow(10, current_length)):
                number_string = str(i)
                padding_zeros = "0" * (current_length - len(number_string))
                print "generate %s" % i
                yield (padding_zeros + number_string).encode("ascii")
    
    for i in my_gen():
        print "iterate %s" % i
    

    【讨论】:

    • 生成器不是状态机 -1:en.wikipedia.org/wiki/Finite-state_machine。另外,主生成器接口是next
    • 我认为它是(一个非常简单的):每次调用 next() 都会改变它的状态,允许它前进或停止。 (我将第二个 'iter' 编辑为 'next()')
    • 这不是状态机的定义。
    • 我对此的理解可能来自.net。yield在编译时生成状态机。我认为它在python中是相似的
    【解决方案3】:

    好的,你知道生成器,所以yield 部分不需要解释。很好。

    那么这条线实际上是做什么的?不是很多:

    它将padding_zerosnumber_string 连接起来,然后将结果编码为ASCII。在 Python 2.7 中是无操作的,因为字符串以 ASCII 开头(根据定义,它只包含 ASCII 数字)。

    在 Python 3 中,情况会有所不同;这里.encode() 会将字符串转换为bytes 对象。但在 Python 2 中,它没有任何意义。

    【讨论】:

    • 谢谢 - 可能是这段代码最初是用 Python 3 编写的,这可以解释为什么它在 Python 2 中显示为无操作。虽然不能 100% 确定。感谢您的回答,很抱歉如此无知。
    【解决方案4】:

    在这种情况下,yield 用于执行惰性求值。下面的代码大致等价:

    def f(...):
        for current_length in range(4, max_length + 1):
            for i in range(0, pow(10, current_length)):
                number_string = str(i)
                padding_zeros = "0" * (current_length - len(number_string))
                yield (padding_zeros + number_string).encode("ascii")
    
    result = list(f())
    

    def f(...):
        result = list()
        for current_length in range(4, max_length + 1):
            for i in range(0, pow(10, current_length)):
                number_string = str(i)
                padding_zeros = "0" * (current_length - len(number_string))
                result.append((padding_zeros + number_string).encode("ascii"))
        return result
    
    result = f()
    

    你可以在你的代码翻译中跟着第二个。

    【讨论】:

    • 除了第二个版本返回一个列表,而生成器将一个一个地生成每个元素。
    • @Marcin 当然。但我认为 OP 并不关心这一点:)
    • 嗯,很高兴了解两者之间的区别,但是当我开始转换时这应该特别有用(其余部分仍在处理伪代码)。
    猜你喜欢
    • 1970-01-01
    • 2017-12-04
    • 1970-01-01
    • 2013-11-13
    • 2012-11-28
    • 1970-01-01
    • 2020-03-19
    • 2012-08-01
    • 1970-01-01
    相关资源
    最近更新 更多