使用索引对Perl中的列表进行排序以对另一个列表进行排序和索引

时间:2012-09-14 15:17:16

标签: perl sorting

假设我有一个包含单词的列表,另一个包含与这些单词相关的置信度的列表:

my @list = ("word1", "word2", "word3", "word4");
my @confidences = (0.1, 0.9, 0.3, 0.6);

我想获得第二对列表,其中@list的元素的排序顺序高于0.4,以及相应的置信度。我如何在Perl中做到这一点? (即使用用于排序另一个列表的索引列表)

在上面的示例中,输出为:

my @sorted_and_thresholded_list = ("word2", "word4");
my @sorted_and_thresholded_confidences = (0.9, 0.6);
  • @list中的条目可能不是唯一的(即排序应该是稳定的)
  • 排序应按降序排列。

5 个答案:

答案 0 :(得分:5)

处理并行数组时,必须使用索引。

my @sorted_and_thresholded_indexes =
    sort { $confidences[$b] <=> $confidences[$a] }
     grep $confidences[$_] > 0.4,
      0..$#confidences;

my @sorted_and_thresholded_list =
   @list[ @sorted_and_thresholded_indexes ];
my @sorted_and_thresholded_confidences =
   @confidences[ @sorted_and_thresholded_indexes ];

答案 1 :(得分:3)

使用List::MoreUtils'pairwisepart

use List::MoreUtils qw(pairwise part);
my @list = ("word1", "word2", "word3", "word4");
my @confidences = (0.1, 0.9, 0.3, 0.6);

my $i = 0;
my @ret = part { $i++ % 2 } 
          grep { defined } 
          pairwise { $b > .4 ? ($a, $b) : undef } @list, @confidences;

print Dumper @ret;

输出:

$VAR1 = [
          'word2',
          'word4'
        ];
$VAR2 = [
          '0.9',
          '0.6'
        ];

答案 2 :(得分:1)

如果您确定不会有重复的单词,我认为使用散列可能更容易,例如:

my %hash = ( "word1" => 0.1,
             "word2" => 0.9,
             "word3" => 0.3,
             "word4" => 0.6
           );

然后,您可以迭代哈希中的键,只找出符合条件的键:

foreach my $key (keys %hash) {
    if ($hash{$key} > 0.4) {
        print $key;
    }
}

答案 3 :(得分:1)

虽然ikegami已经说明了我的首选解决方案 - 使用指标 - 但也可以选择将数组组合成二维数组(*)。好处是数据全部收集到相同的数据结构中,因此易于操作。

use strict;
use warnings;
use Data::Dumper;

my @list = ("word1", "word2", "word3", "word4");
my @conf = (0.1, 0.9, 0.3, 0.6);
my @comb;

for (0 .. $#list) {                       # create two-dimensional array
    push @comb, [ $list[$_], $conf[$_] ];
}

my @all = sort { $b->[1] <=> $a->[1] }    # sort according to conf
          grep { $_->[1] > 0.4 } @comb;   # conf limit

my @list_done = map $_->[0], @all;        # break the lists apart again
my @conf_done = map $_->[1], @all;

print Dumper \@all, \@list_done, \@conf_done;

<强>输出:

$VAR1 = [
          [
            'word2',
            '0.9'
          ],
          [
            'word4',
            '0.6'
          ]
        ];
$VAR2 = [
          'word2',
          'word4'
        ];
$VAR3 = [
          '0.9',
          '0.6'
        ];

(*)=使用散列也是一种选择,假设1)原始顺序不重要,2)所有单词都是唯一的。但是,除非快速查找是一个问题,否则使用数组没有任何缺点。

答案 4 :(得分:1)

my @list = ("word1", "word2", "word3", "word4");
my @confidences = (0.1, 0.9, 0.3, 0.6);

my @result = map { $list[$_] }
              sort { $confidences[$b] <=> $confidences[$a] }
                 grep { $confidences[$_] > 0.4 } (0..$#confidences);