How can I do a for() or foreach() loop in Python and Perl, respectively, that only prints every third index? I need to move every third index to a new array.
Beautiful. Python slices give me erections.
Dominic Bou-Samra
2009-09-23 09:35:52
http://en.wikipedia.org/wiki/Diphallia ?
kaizer.se
2009-09-23 13:22:39
+11
A:
Python
print list[::3] # print it
newlist = list[::3] # copy it
Perl
for ($i = 0; $i < @list; $i += 3) {
print $list[$i]; # print it
push @y, $list[$i]; # copy it
}
tuergeist
2009-09-23 09:33:15
+2
A:
In Perl:
$size = @array;
for ($i=0; $i<$size; $i+=3) # or start from $i=2, depends what you mean by "every third index"
{
print "$array[$i] ";
}
Igor Oks
2009-09-23 09:34:57
+8
A:
Perl 5.10 new state variables comes in very handy here:
my @every_third = grep { state $n = 0; ++$n % 3 == 0 } @list;
Also note you can provide a list of elements to slice:
my @every_third = @list[ 2, 5, 8 ]; # returns 3rd, 5th & 9th items in list
You can dynamically create this slice list using map (see Gugod's excellent answer) or a subroutine:
my @every_third = @list[ loop( start => 2, upto => $#list, by => 3 ) ];
sub loop {
my ( %p ) = @_;
my @list;
for ( my $i = $p{start} || 0; $i <= $p{upto}; $i += $p{by} ) {
push @list, $i;
}
return @list;
}
Update:
Regarding runrig's comment... this is "one way" to make it work within a loop:
my @every_third = sub { grep { state $n = 0; ++$n % 3 == 0 } @list }->();
/I3az/
draegtun
2009-09-23 12:01:48
state is nice. But if you execute that line more than once, it'll only work the first time unless the list length is a multiple of 3.
runrig
2009-09-23 15:09:22
Well pointed out. Its slightly annoying but not surprising feature of state variables which u can get around by encapsulating in an anonymous sub (see my update).
draegtun
2009-09-23 18:33:47
Why not do `map { $_ * 3 } 0 .. $MAX / 3` and use that for your slice index?
Chris Lutz
2009-09-23 18:35:58
Indeed why not. In fact I had already upvoted Gugod's answer on this ;-) I didn't use map because there was already a similar answer here but for some reason it as now been deleted?
draegtun
2009-09-23 18:44:15
+11
A:
Perl:
As with draegtun's answer, but using a count var:
my $i;
my @new = grep {not ++$i % 3} @list;
Adam Bellaire
2009-09-23 12:39:48
And can be nicely put in a do block: my @new = do { my $i; grep {not ++$i % 3} @list };
draegtun
2009-09-23 12:45:36
+1
A:
@array = qw(1 2 3 4 5 6 7 8 9); print @array[(grep { ($_ + 1) % 3 == 0 } (1..$#array))];
Alex
2009-09-23 15:10:05
+6
A:
Perl:
# The initial array
my @a = (1..100);
# Copy it, every 3rd elements
my @b = @a[ map { 3 * $_ } 0..$#a/3 ];
# Print it. space-delimited
$, = " ";
say @b;
gugod
2009-09-23 15:22:02
+3
A:
You could do a slice in Perl.
my @in = ( 1..10 );
# need only 1/3 as many indexes.
my @index = 1..(@in/3);
# adjust the indexes.
$_ = 3 * $_ - 1 for @index;
# These would also work
# $_ *= 3, --$_ for @index;
# --($_ *= 3) for @index
my @out = @in[@index];
Brad Gilbert
2009-09-23 20:33:05