按第二个值(或总和)对“元组”排序

2024-10-01 04:51:24 发布

您现在位置:Python中文网/ 问答频道 /正文

我的目的是做一个子程序,它接受一个随机的4-toop,sorts的列表 然后非破坏性地按每个toop的和从大到小,并返回排序后的列表。在

输出示例应为:

---- random 4-toops:
toop 1: (93 97 78 77); 345
toop 2: (-1 82 92 -45); 128
toop 3: (62 25 -31 -4); 52
toop 4: (-77 -86 18 36); -109
toop 5: (-72 -96 -83 -6); -257
---- random 4-toops sorted by sum:
toop 1: (93 97 78 77); sum = 345
toop 2: (-1 82 92 -45); sum = 128
toop 3: (62 25 -31 -4); sum = 52
toop 4: (-77 -86 18 36); sum = -109
toop 5: (-72 -96 -83 -6); sum = -257

这里是我的Python变体代码,它已经在工作:

^{pr2}$

所以我遇到了这个问题:在Python中,我简单地将sum列表和tuples列表压缩在一起,然后按每个tuple中的第二个元素排序,这总是sum。perl中是否有一个等效的函数可以根据元组的第二个元素进行排序?这是我目前为止的尝试。在

sub sort_random_4_toops_by_sum {

    my ( @sorted_toops,@sorted_toops2, @sorted_toops_sums, @sortedtoops3 ) = @_;

    @sorted_toops2 = map { [ $_, sum( @$_ ) ] } @sorted_toops;
    @sorted_toops_sums = reverse sort { $a->[1] <=> $b->[1] } @sorted_toops2;

    my @sortedtoops3 = map { $_->[0] } @sorted_toops_sums;

    return \@sortedtoops3;
}

它告诉我:

Can't locate List/Tuples.pm in @INC

生成正确输出的测试代码:

sub test_step_3 {

    my $toops = gen_random_4_toops( 1, 100, 5 );

    print "---- random 4-toops:\n";

    my $tn = 1;
    foreach ( @{ sort_random_4_toops_by_sum( @{$toops} ) } ) {
        print "toop $tn:\t(@{$_}); " . sum( @{$_} ) . "\n";
        $tn++;
    }

    print "---- random 4-toops sorted by sum:\n";

    my $sorted_toops = sort_random_4_toops_by_sum( @{$toops} );

    $tn = 1;
    foreach ( @{$sorted_toops} ) {
        print "toop $tn:\t(@{$_}); sum = " . sum( @{$_} ) . "\n";
        $tn++;
    }
}

Tags: 列表by排序myrandomsorttnsum
2条回答

首先,它们是元组。我以前从未见过“toop”在数学或编程中用来表示元组

您自己的代码的问题是您将sort_random_4_toops_by_sum的参数复制到了错误的位置。你有

my @sorted_toops = ();
my ( @sorted_toops2, @sorted_toops_sums, @sortedtoops3 ) = @_;

代码期望未排序的数据位于(非常糟糕的名称)@sorted_toops。您还声明了@sortedtoops3两次。如果您更改如下,您的程序将正常工作

^{pr2}$

我建议您使用^{}模块,它提供了一个rev_nsort_by(反向数字排序)实用程序函数。使用它,您可以将您的sort_random_4_toops_by_sum减少到这个值

use List::UtilsBy qw/ rev_nsort_by /;

sub sort_random_4_toops_by_sum {
    [ rev_nsort_by { sum @$_ } @_ ];
}

你的机器太多了。既然我不能理解你的代码,我就从头开始工作。我还将假设您的“4元组”只是4个元素的数组引用,因为这就是它们需要的全部。在

use List::Util 'sum';

my @tuples = generate_a_bunch_of_random_tuples();

# Zip each tuple with its sum
my @tuples_with_sums = map { [ $_, sum(@$_) ] } @tuples;

my @sorted_with_sums = reverse sort { $a->[1] <=> $b->[1] } @tuples_with_sums;

my @sorted = map { $_->[0] } @sorted_with_sums;

事实上,在Schwartzian transform的实例中,可以将整个过程作为单个语句来完成:

^{pr2}$

但为了便于理解,我把它写了很久。在

“zip”(可以从List::MoreUtils获得)只有在已经有多个并行列表的情况下才真正有用。如果输出列表的每个元素都依赖于单个输入列表中的一个元素,map也能正常工作——事实上,效果更好。在

相关问题 更多 >