gpt4 book ai didi

python - 将带有 yield 语句的 Ruby 循环迭代转换为 Python

转载 作者:数据小太阳 更新时间:2023-10-29 08:35:38 26 4
gpt4 key购买 nike

我正在尝试通过翻译 Jamis Buck 的《程序员迷宫》一书中的代码来自学 Python。这是一本很棒的书,但它是用 Ruby 编写的,我在理解一些 Ruby 代码时遇到了困难。

为了理解这个问题,我包含了一个简化版本的代码库

细胞.rb

class Cell
attr_reader : row, :column

def initialize(row, column)
@row, @column = row, column
end

网格.rb

require 'cell'
class Grid
attr_reader :rows, :columns

def initialize(rows, columns)
@rows = rows
@columns = columns
@grid = prepare_grid
end

def prepare_grid
Array.new(rows) do |row|
Array.new(columns) do |column|
Cell.new(row, column)
end
end
end

到目前为止一切顺利。以上所有内容都很容易理解并转换为 Python。然后有下面两个函数作为Grid类的一部分。

def each_row
@grid.each do |row|
yield row
end
end

def each_cell
each_row do |row|
row.each do |cell|
yield cell if cell
end
end
end

这里的最后两个函数实际上在做什么?我发现了类似的东西 here这让我认为 Python 版本需要接受一个可选的 lambda 变量,测试它是否不为 null,如果不是,则运行与该变量关联的代码。问题是我知道这些函数的目的是成为一个迭代器,我认为添加 lambda 不会有帮助。

已经有一个有点类似的问题here在 StackOverflow 上,这让我觉得答案微不足道,但我对 Ruby 的了解还不够,无法凭直觉得出答案或向 Google 提出正确的问题。

最佳答案

Then there are the following two functions as part of the Grid class.

这些不是函数。它们是方法。

def each_row
@grid.each do |row|
yield row
end
end

def each_cell
each_row do |row|
row.each do |cell|
yield cell if cell
end
end
end

What are the last two functions here actually doing?

each_row方法将一个 block 作为参数,并会依次yield @grid 数组的所有元素. @grid 的结构是一个数组的数组,表示单元格的行。换句话说,each_row 将连续yield 网格的每一行,即它是行的迭代器方法。

each_cell方法以一个 block 作为参数,将依次产生网格中行数组的所有元素@grid 数组。换句话说,each_cell 将连续 yield 网格的每个单元格(如果存在),即它是单元格的迭代器方法。

Python 的字面翻译应该是这样的(未经测试):

def each_row(self, f):
self.grid.each(lambda row: f(row))

def each_cell(self, f):
self.each_row(lambda row: lambda cell: if cell: f(cell))

但是,以这种方式将代码从一种语言翻译成另一种语言是没有意义的。在 Python 中使用 lambda 进行迭代是非惯用的。 Python 使用迭代器进行迭代。因此,与其使用 each_roweach_cell 迭代器方法,不如使用返回迭代器的 row_iteratorcell_iterator getter行和单元格的对象,这样您就可以执行以下操作:

for cell in grid.cell_iterator

代替

grid.each_cell(lambda cell: …)

像这样的(也未经测试):

def row_iterator(self):
for row in self.grid: yield row

def cell_iterator(self):
for row in self.row_iterator:
for cell in row:
if cell: yield cell

当您将代码从一种语言“翻译”成另一种语言时,您不能只是逐行、逐语句、逐表达式、逐子例程、逐类地翻译它,等等。您需要从头开始重新设计它,使用社区的模式、实践和习语以及语言及其核心和标准库中的类型、类、子例程、模块等。

否则,您只能使用编译器。编译器的字面定义是“将程序从一种语言翻译成另一种语言的程序”。如果这就是您想要做的全部,请使用编译器。但是,如果您希望翻译后的代码具有可读性、可理解性、可维护性和惯用性,则只能由人来完成。

关于python - 将带有 yield 语句的 Ruby 循环迭代转换为 Python,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/44794203/

26 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com