什么是Python迭代器的Perl版本? [英] What is the Perl version of a Python iterator?

查看:132
本文介绍了什么是Python迭代器的Perl版本?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我在工作中学习Perl并享受它。我通常用Python做我的工作,但老板想要Perl。

I am learning Perl at my work and enjoying it. I usually do my work in Python but boss wants Perl.

Python和Perl中的大多数概念匹配得很好:Python dictionary = Perl hash; Python元组= Perl列表; Python list = Perl数组;等等。

Most of the concepts in Python and Perl match nicely: Python dictionary=Perl hash; Python tuple=Perl list; Python list=Perl array; etc.

问题:是否存在迭代器 /生成器?

Question: Is there a Perl version of the Python form of an Iterator / Generator?

一个例子:生成Fibonacci数字的经典Python方法是:

An example: A Classic Python way to generate the Fibonacci numbers is:

#!/usr/bin/python

def fibonacci(mag):
     a, b = 0, 1
     while a<=10**mag:
         yield a
         a, b = b, a+b

for number in fibonacci(15):  
     print "%17d" % number

如果你想根据需要生成更大的列表的子部分,迭代器也很有用。 Perl'列表'似乎更加静态 - 更像是一个Python元组。在Perl中, foreach 可以是动态的还是仅基于静态列表?

Iterators are also useful if you want to generate a subsection of a much larger list as needed. Perl 'lists' seem more static - more like a Python tuple. In Perl, can foreach be dynamic or is only based on a static list?

Iterator的Python形式是我已经习惯的表单,我没有在Perl中找到它...除了在循环或递归中写入或生成一个巨大的静态列表之外,我如何(为ex)在Perl中写入Fibonacci子例程?我错过了Perl 收益吗?

The Python form of Iterator is a form that I have gotten used to, and I do not find it documented in Perl... Other than writing this in loops or recursively or generating a huge static list, how do I (for ex) write the Fibonacci subroutine it in Perl? Is there a Perl yield that I am missing?

具体 - 我怎么写这个:

Specifically -- how do I write this:

#!/usr/bin/perl
use warnings; use strict; # yes -- i use those!

sub fibonacci {
   # What goes here other than returning an array or list? 
}

foreach my $number (fibonacci(15)) { print $number . "\n"; }

提前感谢对新手的善意......

Thanks in advance to being kind to the newbie...

推荐答案

对于比Python的生成器更灵活的解决方案,我编写了模块 List :: Gen ,提供随机访问延迟生成器数组:

For an even more flexible solution than Python's generators, I have written the module List::Gen on CPAN which provides random access lazy generator arrays:

use List::Gen;

my $fib; $fib = cache gen {$_ < 2  ? $_ : $$fib[$_ - 1] + $$fib[$_ - 2]};

say "@$fib[0 .. 15]";  #  0 1 1 2 3 5 8 13 21 34 55 89 144 233 377 610

由于发电机假装是数组,它们可以与普通的perl代码无缝混合。还有一种面向对象的方法:

Since generators pretend to be arrays, they can mix seamlessly with normal perl code. There is also an object oriented approach:

my $fib; $fib = cache gen {$_ < 2 ? $_ : $fib->get($_ - 1) + $fib->get($_ - 2)};

say join ' ' => $fib->slice(0 .. 15);

在每种情况下,生成器都是惰性的,在创建时不计算任何内容,然后只计算所需的值满足切片。 Fibonacci序列的递归定义多次调用自身,因此 cache 函数用于确保每个值仅计算一次。

In each case, the generator is lazy, calculating nothing upon creation, and then calculating only those values required to satisfy the slices. The recursive definition of the Fibonacci sequence calls itself many times, so the cache function is used to make sure each value is only calculated once.

你也可以使用生成器作为迭代器:

You can also use generators as iterators:

while (my $num = $fib->next) {
    last if $num > 10**15;
    print "$_\n";
}

$ fib-> next 也可以写成 $ fib->()。由于生成器仍然是随机访问,您可以 $ fib-> reset() $ fib-> index = 10;

$fib->next can also be written $fib->(). Since the generator is still random access, you can $fib->reset() or $fib->index = 10;

如果您有任何疑问,请告诉我。

Let me know if you have any questions.

更新:

我发布了一个新版本的模块(0.80),可以更容易地在生成器中使用迭代算法。这是一个与OP的例子非常相似的例子:

I have released a new version of the module (0.80) that makes it easier to use iterative algorithms in generators. Here is an example that closely mirrors the OP's example:

use List::Gen '*';

sub fibonacci {
    my $limit   = 10**shift;
    my ($x, $y) = (0, 1);

    While {$_ < $limit} gather {
        ($x, $y) = ($y, take($x) + $y)
    }
}

say for @{fibonacci 15};

如果你使用bigint; 之前或之后当然,您可以:

if you use bigint; before or at the top of the sub, you can of course:

say for @{fibonacci 400}; # or more

这篇关于什么是Python迭代器的Perl版本?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆