什么是Python迭代器的Perl版本?
我在工作中学习Perl,并享受它。我通常用Python做我的工作,但老板想要Perl Python和Perl中的大多数概念非常匹配:Python字典=Perl哈希;Python tuple=Perl列表;pythonlist=Perl数组;等等 问题:是否有一个Perl版本的Python形式的/Generator 例如:生成斐波那契数的经典Python方法是:什么是Python迭代器的Perl版本?,python,perl,iterator,Python,Perl,Iterator,我在工作中学习Perl,并享受它。我通常用Python做我的工作,但老板想要Perl Python和Perl中的大多数概念非常匹配:Python字典=Perl哈希;Python tuple=Perl列表;pythonlist=Perl数组;等等 问题:是否有一个Perl版本的Python形式的/Generator 例如:生成斐波那契数的经典Python方法是: #!/usr/bin/python def fibonacci(mag): a, b = 0, 1 while a
#!/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
提前感谢您对新手的友好…这里有一个很好的实用示例和一篇PDF文章。。。但是我对Perl太生疏了,无法尝试直接实现您的挑战(正如您将看到的,PDF中的示例和方法都使用了不太直接的方法)。有一个很好的实用示例和一篇PDF文章。。。但是我对Perl太生疏了,无法尝试直接实现您的挑战(正如您将看到的,PDF中的示例和方法都使用了一种不太直接的方法)。有一种类似的方法来生成迭代器/生成器,但它不是Python上的“一流公民” 在Perl中,如果您看不到您想要的内容(经过一次强制到第一次!),您可以使用类似于基于Perl闭包和匿名子例程的Python迭代器的方法 考虑:
use strict; use warnings;
sub fibo {
my ($an, $bn)=(1,0);
my $mag=(shift || 1);
my $limit=10**$mag;
my $i=0;
return sub {
($an, $bn)=($bn, $an+$bn);
return undef if ($an >=$limit || wantarray );
return $an;
}
}
my $num;
my $iter=fibo(15);
while (defined($num=$iter->()) ) { printf "%17d\n", $num; }
subfibo
维护一个Perl,允许维护持久变量。你可以通过拥有一个类似C/C++的模块来完成同样的操作。在fibo
内部,一个匿名子例程执行返回下一个数据项的工作
引用“在你了解标量和列表上下文之间的区别之前,你会很痛苦”——第69页(一本极力推荐的书,顺便说一句…)
在这种情况下,annon子对象仅返回一个值。我在Perl中知道的唯一可以在标量上下文中工作的循环机制是而;我想其他人在继续之前会先填好名单。因此,如果在列表上下文中调用anon-sub,它将尽职尽责地返回下一个fibonacci数,这与Python对迭代器的调用不同,循环将终止。这就是为什么我将返回undef if。。。。wantarray
,因为它在编写的列表上下文中不起作用
有办法解决这个问题。实际上,您可以编写类似于map
foreach
等的子例程,但它并不像Python那样简单。您需要在foreach循环中使用一个附加函数。折衷是Perl方法具有巨大的功能和灵活性
您可以在Mark Jason Dominus的优秀著作《高阶Perl》中阅读有关Perl迭代器的更多信息。brian d foy在Perl评论中也有一篇关于Interators的优秀文章。有一种类似的方法来生成迭代器/生成器,但它不是Python上的“一流公民”
在Perl中,如果您看不到您想要的内容(经过一次强制到第一次!),您可以使用类似于基于Perl闭包和匿名子例程的Python迭代器的方法
考虑:
use strict; use warnings;
sub fibo {
my ($an, $bn)=(1,0);
my $mag=(shift || 1);
my $limit=10**$mag;
my $i=0;
return sub {
($an, $bn)=($bn, $an+$bn);
return undef if ($an >=$limit || wantarray );
return $an;
}
}
my $num;
my $iter=fibo(15);
while (defined($num=$iter->()) ) { printf "%17d\n", $num; }
subfibo
维护一个Perl,允许维护持久变量。你可以通过拥有一个类似C/C++的模块来完成同样的操作。在fibo
内部,一个匿名子例程执行返回下一个数据项的工作
引用“在你了解标量和列表上下文之间的区别之前,你会很痛苦”——第69页(一本极力推荐的书,顺便说一句…)
在这种情况下,annon子对象仅返回一个值。我在Perl中知道的唯一可以在标量上下文中工作的循环机制是而;我想其他人在继续之前会先填好名单。因此,如果在列表上下文中调用anon-sub,它将尽职尽责地返回下一个fibonacci数,这与Python对迭代器的调用不同,循环将终止。这就是为什么我将返回undef if。。。。wantarray
,因为它在编写的列表上下文中不起作用
有办法解决这个问题。实际上,您可以编写类似于map
foreach
等的子例程,但它并不像Python那样简单。您需要在foreach循环中使用一个附加函数。折衷是Perl方法具有巨大的功能和灵活性
您可以在Mark Jason Dominus的优秀著作《高阶Perl》中阅读有关Perl迭代器的更多信息。brian d foy在Perl评论中也有一篇关于Interators的优秀文章。迭代器的概念在Perl中有点不同。基本上,您希望在持久变量上返回一个一次性子例程“closed”
use bigint;
use strict;
use warnings;
sub fibonacci {
my $limit = 10**( shift || 0 );
my ( $a, $b ) = ( 0, 1 );
return sub {
return if $a > $limit;
( my $r, $a, $b ) = ( $a, $b, $a + $b );
return $r;
};
}
my $fit = fibonacci( 15 );
my $n = 0;
while ( defined( my $f = $fit->())) {
print "F($n): $f\n";
$n++;
}
如果你不喜欢while
循环,那么这里有两个语法糖,基本上完成了一个each item循环:
sub iterate ($$) {
my $iter = shift;
my $action = shift;
while ( defined( my $nextval = $iter->())) {
local *_ = \$nextval;
$action->( $_ );
}
return;
}
iterate fibonacci( 15 ) => sub { print "$_\n"; };
sub iter (&$) {
my $action = shift;
my $iter = shift;
while ( defined( my $nextval = $iter->())) {
local *_ = \$nextval;
$action->( $_ );
}
return;
}
iter { print "$_\n" } fibonacci( 15 );
迭代器的概念在Perl中有点不同。基本上,您希望在持久变量上返回一个一次性子例程“closed”
use bigint;
use strict;
use warnings;
sub fibonacci {
my $limit = 10**( shift || 0 );
my ( $a, $b ) = ( 0, 1 );
return sub {
return if $a > $limit;
( my $r, $a, $b ) = ( $a, $b, $a + $b );
return $r;
};
}
my $fit = fibonacci( 15 );
my $n = 0;
while ( defined( my $f = $fit->())) {
print "F($n): $f\n";
$n++;
}
如果你不喜欢while
循环,那么这里有两个语法糖,基本上完成了一个each item循环:
sub iterate ($$) {
my $iter = shift;
my $action = shift;
while ( defined( my $nextval = $iter->())) {
local *_ = \$nextval;
$action->( $_ );
}
return;
}
iterate fibonacci( 15 ) => sub { print "$_\n"; };
sub iter (&$) {
my $action = shift;
my $iter = shift;
while ( defined( my $nextval = $iter->())) {
local *_ = \$nextval;
$action->( $_ );
}
return;
}
iter { print "$_\n" } fibonacci( 15 );
这本优秀的书(在指定的链接上免费提供)包含了大量相关主题的信息,特别是有一整章关于迭代器的内容。通过“更高阶”,作者暗示了使用Perl的功能作为一种具有一流函数的函数式语言来实现各种很酷的东西。这真的是一本非常好的书——我读了大部分,关于迭代器和流的章节非常棒。如果您打算编写Perl代码,我强烈建议您至少浏览一下它。这本优秀的书(在指定的链接上免费提供)包含了大量有关相关主题的信息,特别是有一整章关于迭代器。通过“更高阶”,作者暗示了使用Perl的功能作为一种具有一流函数的函数式语言来实现各种很酷的东西。这真是一个好消息
while (my $num = $fib->next) {
last if $num > 10**15;
print "$_\n";
}
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};
say for @{fibonacci 400}; # or more
use strict;
use warnings;
use Memoize;
memoize('fib');
foreach my $i (1..15) {
print "$i -> ",fib($i),"\n";
}
sub fib {
my $n = shift;
return $n if $n < 2;
fib($n-1) + fib($n-2);
}
#!/usr/bin/perl -w
use strict; use warnings;
use Alef;
my $fibo;
BEGIN {
my ($a, $b) = (0, 1);
$fibo = sub {
($a, $b) = ($b, $a+$b);
$a;
}
}
my $fibonacci = new Alef($fibo);
foreach my $number ($fibonacci->take(15)){ print $number . "\n"; }
sub take {
my ($self,$n) = (@_);
my @these = ();
my $generator = $self->{'generator'};
for (1..$n){
push(@these,$self->{'this'});
$self->{'this'} = &$generator($self->{'this'});
}
@these;
}
use 5.016;
use warnings;
use Coro::Generator;
sub gen_fibonacci {
my $mag = shift;
generator {
my ($a, $b) = (0, 1);
while ($a <= 10 ** $mag) {
yield $a;
($a, $b) = ($b, $a + $b);
}
yield undef; # stop it!
};
}
my $fibonacci = gen_fibonacci(15);
while (defined (my $number = $fibonacci->())) {
printf "%17d\n", $number;
}