Python 迭代器的 Perl 版本是什么?

What is the Perl version of a Python iterator?(Python 迭代器的 Perl 版本是什么?)
本文介绍了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 列表=Perl 数组;等等.

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

问题:有没有 Perl 版本的 Python 形式的 Iterator/生成器?

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

一个例子:生成斐波那契数的经典 Python 方法是:

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


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 中编写斐波那契子程序?是否有我缺少的 Perl yield?

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:

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 . "
"; }


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


为了比 Python 的生成器更灵活的解决方案,我编写了模块 List::Gen 在 CPAN 上提供随机访问惰性生成器数组:

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);

在每种情况下,生成器都是惰性的,在创建时不计算任何内容,然后只计算满足切片所需的值.斐波那契数列的递归定义多次调用自身,所以使用 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 "$_

$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};

如果你在 sub 之前或顶部 使用 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 版本是什么?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持跟版网!



python arbitrarily incrementing an iterator inside a loop(python在循环内任意递增迭代器)
Joining a set of ordered-integer yielding Python iterators(加入一组产生 Python 迭代器的有序整数)
Iterating over dictionary items(), values(), keys() in Python 3(在 Python 3 中迭代字典 items()、values()、keys())
How to create a generator/iterator with the Python C API?(如何使用 Python C API 创建生成器/迭代器?)
Python generator behaviour(Python 生成器行为)
Splitting a string into 2-letter segments(将字符串拆分为 2 个字母的段)