在 Ruby 和 Python 中使用 Yield 创建列表
我正在尝试想出一种优雅的方法来从在 Python 和 Ruby 中生成值的函数创建列表。
在 Python 中:
def foo(x):
for i in range(x):
if bar(i): yield i
result = list(foo(100))
在 Ruby 中:
def foo(x)
x.times {|i| yield i if bar(i)}
end
result = []
foo(100) {|x| result << x}
虽然我喜欢使用两种语言工作,但我总是对 Ruby 版本必须初始化列表然后填充它感到有点困扰。 Python 的 yield
可以实现简单的迭代,这非常棒。 Ruby 的 yield
调用一个块,这也很棒,但是当我只想填充一个列表时,感觉有点笨拙。
有没有更优雅的 Ruby 方式?
更新 重新设计了示例以表明函数生成的值的数量不一定等于 x。
I'm trying to come up with an elegant way of creating a list from a function that yields values in both Python and Ruby.
In Python:
def foo(x):
for i in range(x):
if bar(i): yield i
result = list(foo(100))
In Ruby:
def foo(x)
x.times {|i| yield i if bar(i)}
end
result = []
foo(100) {|x| result << x}
Although I love working in both languages, I've always been a bit bothered by the Ruby version having to initialize the list and then fill it. Python's yield
results in simple iteration, which is great. Ruby's yield
invokes a block, which is also great, but when I just want to fill a list, it feels kinda clunky.
Is there a more elegant Ruby way?
UPDATE Reworked the example to show that the number of values yielded from the function isn't necessarily equal to x.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(7)
因此,对于您的新示例,请尝试以下操作:
基本上,除非您正在编写自己的迭代器,否则您在 Ruby 中并不经常需要
yield
。 如果您停止尝试使用 Ruby 语法编写 Python 习惯用法,您可能会做得更好。So, for your new example, try this:
Basically, unless you're writing an iterator of your own, you don't need
yield
very often in Ruby. You'll probably do a lot better if you stop trying to write Python idioms using Ruby syntax.对于 Python 版本,我将使用生成器表达式,例如:
或者对于过滤值的这种特定情况,甚至更简单
For the Python version I would use a generator expression like:
Or for this specific case of filtering values, even more simply
与 Python 代码(使用 Ruby 生成器)完全相同的代码是:
在上面,列表是延迟生成的(就像在 Python 示例中一样); 看:
The exact equivalent of your Python code (using Ruby Generators) would be:
In the above, the list is lazily generated (just as in the Python example); see:
我知道这并不完全是您想要的,但是用 ruby 表达示例的更优雅的方式是:
I know it's not exactly what you were looking for, but a more elegant way to express your example in ruby is:
对于 stbuton 发布的 Python 列表理解版本,如果您需要使用 xrange 而不是 range想要一台发电机。 range 将在内存中创建整个列表。
For the Python list comprehension version posted by stbuton use xrange instead of range if you want a generator. range will create the entire list in memory.
yield
在 ruby 和 python 中意味着不同的东西。 在 ruby 中,如果我没记错的话,你必须指定一个回调块,而 python 中的生成器可以传递并屈服于持有它们的人。yield
means different things ruby and python. In ruby, you have to specify a callback block if I remember correctly, whereas generators in python can be passed around and yield to whoever holds them.任何涉及一系列值的事情最好用一个范围来处理,而不是
times
和数组生成。Anything involving a range of values is best handled with, well, a range, rather than
times
and array generation.