繁体   English   中英

Perl等同于(Python-)列表理解

[英]Perl equivalent of (Python-) list comprehension

我正在寻找在Perl中表达此Python代码段的方法:

data = {"A": None, "B": "yes", "C": None}
key_list = [k for k in data if data[k]]  
# in this case the same as filter(lambda k: data[k], data) but let's ignore that

因此,从一种角度看,我只想要键值为Noneundef的键。 从另一种角度来看,我想要的是简洁的perl等同于带条件列表理解

我想你想要grep

#!/usr/bin/env perl
use strict;
use warnings;

my %data = ( A => undef, B => 'yes', C => undef );

my @keys = grep { defined $data{$_} } keys %data;

print "Key: $_\n" for @keys;

我还认为输入速度太慢,因此在发布答案之前应该重新加载页面。 顺便说一句,值为0undef可能是处理值的好方法,但是请确保记住使用的值。 在Perl中,false值和undefined值不是同一回事。 需要说明的是: undef在布尔测试中返回false,但是0 undef返回false。 如果0是有效值,那么您要显式测试定义性,而不仅仅是真实性。 (我之所以这样提,是因为詹姆斯去了0而我又去了,所以你可能不知道这是否重要。)

使用grep

#!/usr/bin/perl

use strict;
use warnings;

my %data = ("A" => 0, "B" => "yes", "C" => 0 );
my @keys = grep { $data{$_} } keys %data;

Grep从右侧列表中返回值,大括号中的表达式将其计算为真值。 正如远距传销员指出的那样,您要确保您了解Perl中的true / false值。 这个问题很好地概述了Perl中的真理。

您可能需要看一下map ,它将大括号中的表达式应用于列表的每个元素并返回结果。 一个例子是:

my @data = ("A" => 0, "B" => 1, "C" => 0 );
my @modified_data = map { $data{$_} + 1 } @data;
print join ' ', @data, "\n";
print join ' ', @modified_data, "\n";

对于主题的变化,请看一下autobox (请参阅其实现autobox :: CoreMoose :: Autobox

use autobox::Core;

my %data = ( A => undef, B => 'yes', C => undef );
my $key_list = %data->keys->grep( sub { defined $data{$_} } );

say "Key: $_" for @$key_list;

# => Key: B


Moose :: Autobox带有键/值'kv',它使代码DRYer:

my $key_list = %data->kv->grep( sub{ defined $_->[1] } )->map( sub{ $_->[0] } );

这是上面的更明确甚至更长的版本:

my $key_list = %data->kv
                    ->grep( sub { my ($k, $v) = @$_; defined $v } )
                    ->map(  sub { my ($k, $v) = @$_; $k }         );

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM