toy list processing problem: collect similar terms

Dr.Ruud rvtol+usenet at xs4all.nl
Sun Sep 26 11:41:23 CEST 2010


On 2010-09-26 06:05, Xah Lee wrote:

> I have a list of lists, where each sublist is labelled by
> a number. I need to collect together the contents of all sublists
> sharing the same label. So if I have the list
>
> ((0 a b) (1 c d) (2 e f) (3 g h) (1 i j) (2 k l) (4 m n) (2 o p) (4 q r) (5 s t))
>
> where the first element of each sublist is the label, I need to
> produce:
>
> output:
> ((a b) (c d i j) (e f k l o p) (g h) (m n q r) (s t))

The input is a string on STDIN,
and the output is a string on STDOUT?


Use a hash:

perl -MData::Dumper -wle '$Data::Dumper::Sortkeys = 1;
   my $t = "((0 a b) (1 c d) (2 e f) (3 g h) (1 i j)"
         . " (2 k l) (4 m n) (2 o p) (4 q r) (5 s t))";

   push @{ $h{ $1 } }, $2 while $t =~ /(\w+)([^)]*)/g;  # gist

   print Dumper \%h;
'

or an array:

perl -wle '
   my $t = "((0 a b) (1 c d) (2 e f) (3 g h) (1 i j)"
         . " (2 k l) (4 m n) (2 o p) (4 q r) (5 s t))";

   push @{$a[$1]},$2 while $t =~ /(\w+)\s+([^)]*)/g; # gist.1
   print "((".join(") (",map join(" ",@$_), at a )."))";  # gist.2
'


Or if the list is not just a string, but a real data structure in the 
script:

perl -wle'
   my $t = [ [qw/0 a b/], [qw/1 c d/], [qw/2 e f/], [qw/3 g h/],
             [qw/1 i j/], [qw/2 k l/], [qw/4 m n/], [qw/2 o p/],
             [qw/4 q r/], [qw/5 s t/] ];

   push @{ $a[ $_->[0] ] }, [ @$_[ 1, 2 ] ] for @$t;  # AoAoA

   printf "((%s))\n", join ") (",
                        map join( " ",
                          map join( " ", @$_ ), @$_
                        ), @a;
'

Etc.

-- 
Ruud




More information about the Python-list mailing list