几乎相同。尽管 Python 和 Ruby 的 yield 的语义有些不同,但在这种情况下,它们几乎完全一致。
Ruby 的 yield 调用一个块,该块被传递给函数,并为其提供参数。
Python 的yield 使该函数成为生成器,并从中生成一个输出。
它们都只在函数的上下文中有意义,所以你的 while 循环太短了,无法使用它。但是,让我们在 Ruby 中以类似的方式作为简化示例:
def numbers_and_doubles(n)
i = 0
while i < n
yield i, 2 * i
i += 1
end
end
这个函数接受一个带有一个参数的块,然后生成不超过该数字的数字及其双精度数,并使用这些参数执行该块:
numbers_and_doubles(5) do |num, double|
puts "#{num} * 2 = #{double}"
end
由于block和回调函数基本是一回事,所以就相当于这个Python:
def numbers_and_doubles(n, callback):
i = 0
while i < n:
callback(i, i*2)
i += 1
def output(num, double):
print(f"{num} * 2 = {double}")
numbers_and_doubles(5, output)
另一方面,Python 的 yield 创建了一个生成器 - 一个返回可以按需生成值的函数的函数:
def numbers_and_doubles(n):
i = 0
while i < n:
yield i, 2 * i
i += 1
使用生成器最自然的方式是通过for 循环:
for num, double in numbers_and_doubles(5):
print(f"{num} * 2 = {double}")
在 Ruby 中,最接近的直译是Enumerator:
def numbers_and_doubles(n)
Enumerator.new do |yielder|
i = 0
while i < n
yielder.yield(i, i*2)
i += 1
end
end
end
使用Enumerator 最自然的方式是使用each(这是Ruby 主义者比for 更喜欢的方式):
numbers_and_doubles(5).each do |num, double|
puts "#{num} * 2 = #{double}"
end
但是,正如我所说,即使它们做了一些稍微不同的事情,上面的原始 Ruby(带有yield)与上面的原始 Python(带有 yield)惊人地相似。它们的使用方式略有不同,但适合每种语言的习语。
在您的情况下,如果您将 yield 完全保留在 Python 中,则使用它的行将与 Ruby 的不同
backtrack do |prev_x, prev_y, x, y|
到 Python 的
for prev_x, prev_y, x, y in backtrack():
您可以在Python yield vs Ruby yield阅读更多内容。
请注意,编写此循环的最自然方法不是使用任何一种语言的while(我会在 Python 中使用 range,在 Ruby 中使用 times),但我希望两者的代码看起来相似语言,用于比较。