python - 从 Ruby 移植到 Python:如何处理“yield”
问题描述
我目前尝试将一段代码从 Ruby 移植到 Python 来做一些算法研究。我没有使用 Ruby 的经验,也不知道如何处理 'yield' 关键字。
该代码用于Myers diff 算法,并在此博客中进行了全面描述
这是我不明白的代码片段:
while x > prev_x and y > prev_y
yield x - 1, y - 1, x, y
x, y = x - 1, y - 1
end
有没有办法在Python中近似这个?
解决方案
几乎一模一样。尽管 Python 和 Ruby 的语义yield
有些不同,但在这种情况下,它们几乎完全一致。
Rubyyield
调用一个传递给函数的块,并为其提供参数。
Pythonyield
使该函数成为生成器,并从中生成一个输出。
它们都只在函数的上下文中有意义,所以只是你的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
由于块与回调函数基本相同,所以它相当于这个 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)
另一方面,Pythonyield
创建了一个生成器——一个返回可以按需生成值的函数的函数:
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
使用 an 最自然的方式Enumerator
是使用each
(这是 Rubyists 更喜欢的for
):
numbers_and_doubles(5).each do |num, double|
puts "#{num} * 2 = #{double}"
end
但是,正如我所说,即使它们做了一些稍微不同的事情,上面的原始 Ruby (with yield
) 与上面的原始 Python (with ) 惊人地相似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
使用任何一种语言(我会range
在 Python 和times
Ruby 中使用),但我希望两种语言看起来相似的代码,以进行比较。
推荐阅读
- c++ - 使用 `std::error_code` 的最佳实践
- python - 拆分列表并保留python中的空格
- c# - 通过 Hangfire 在 Azure 中无法 HttpWebRequest
- python-3.x - 计算列表中所有字符串元素的多次出现?
- r - 调整 showModal 在 Shiny 上显示的图像
- android-recyclerview - 在回收站视图上配置搜索视图
- sql-server - bcp 在 CSV 输出中添加额外字符
- r - 在 R lavaan 中使用 getCov 和一个实际的大相关矩阵
- ios - 为什么我的 ViewController 会自行关闭?
- sql - Postgres COPY 到 hstore 字段中,值中有双引号