Hi Monks,
https://www.codementor.io/sumit12dec/python-tricks-for-beginners-du107t193, '10 Neat Python Tricks' is the title of this link. My perl solutions to these tricks can be seen below. Interestingly in many cases perl solution looks more obvious than python solution. Any comment is welcome.
Update: Confusingly edited IX and X are corrected.
Update 2: X fixed
Update 3: I updated
I. Reversing a string in Python
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
PYTHON
a = "codementor"
print "Reverse is", a[::-1]
PERL
my $a ="GeeksForGeeks"
say 'Reverse is '. reverse $a;
----------------------------------------------------------------------
+----
II. Transposing a Matrix
^^^^^^^^^^^^^^^^^^^^^^^^
PYTHON
mat = [[1, 2, 3], [4, 5, 6]]
zip(*mat)
PERL
use List::MoreUtils qw/each_arrayref/;
my @l = ([1, 2, 3], [4, 5, 6]);
my @a;
my $iter = each_arrayref(@l);
while (my @t = $iter->()) {
push @a, \@t;
}
----------------------------------------------------------------------
+----
III. Store all three values of the list in 3 new variables
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
PYTHON
a = [1, 2, 3]
x, y, z = a
PERL
my @a = qw/1 2 3/;
my ($x, $y, $z) = @a;
----------------------------------------------------------------------
+----
IV. Create a single string from all the elements in list below
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
PYTHON
a = ["Code", "mentor", "Python", "Developer"]
print " ".join(a)
PERL
my @a = qw/Code mentor Python Developer/;
say "@a";
----------------------------------------------------------------------
+----
V. Write a Python code to print
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
PYTHON
list1 = ['a', 'b', 'c', 'd']
list2 = ['p', 'q', 'r', 's']
for x, y in zip(list1,list2):
print x, y
PERL
my @list1 = qw/a b c d/;
my @list2 = qw/p q r s/;
for (my $i=0; $i<@list1; ++$i) {
say "$list[$i] $list2[$i]";
}
----------------------------------------------------------------------
+----
VI. Swap two numbers with one line of code
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
PYTHON
a = 7
b = 5
b, a = a, b
PERL
my ($a, $b) = (7, 5);
($b, $a) = ($a, $b);
----------------------------------------------------------------------
+----
VII. Print "codecodecodecode mentormentormentormentormentor" without u
+sing loops
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
+^^^^^^^^^^
PYTHON
print "code" * 4 + ' ' + "mentor" * 5
PERL
say 'code' x 4, ' ', 'mentor' x 5;
----------------------------------------------------------------------
+----
VIII. Convert it to a single list without using any loops
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
PYTHON
import itertools
a = [[1, 2], [3, 4], [5, 6]]
list(itertools.chain.from_iterable(a))
PERL
my @a = ([1, 2], [3, 4], [5, 6]);
@l = map { @$_ } @a;
----------------------------------------------------------------------
+----
IX. Checking if two words are anagrams
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
PYTHON
from collections import Counter
def is_anagram(str1, str2):
return Counter(str1) == Counter(str2)
PERL
sub is_anagram {
return (join('', sort split('', $_[0])) eq
join('', sort split('', $_[1]))) ? 'True' : 'False';
}
----------------------------------------------------------------------
+----
X. Taking a string input
^^^^^^^^^^^^^^^^^^^^^^^^
For example "1 2 3 4" and return [1, 2, 3, 4]
Remember list being returned has integers in it.
Don't use more than one line of code.
PYTHON
result = map(lambda x:int(x) ,raw_input().split())
PERL
my @r = split /\s+/, <STDIN>;
Re: Python tricks
by hippo (Archbishop) on Dec 18, 2018 at 12:28 UTC
|
Personal choice, but I would swap out the C-ish loop from V:
my @list1 = qw/a b c d/;
my @list2 = qw/p q r s/;
for (0 .. $#list1) {
say "$list1[$_] $list2[$_]";
}
| [reply] [d/l] |
|
|
Your solution is better, more perlish.
| [reply] |
|
|
No, it's not perlish and please don't use it any more.
$# is long deprecated, and will throw exception when using on 5.30 soon.
Thank syphilis for pointing out my misunderstanding!
I am trying to improve my English skills, if you see a mistake please feel free to reply or /msg me a correction
| [reply] |
|
|
|
|
Re: Python tricks
by tybalt89 (Monsignor) on Dec 18, 2018 at 17:52 UTC
|
say 'Reverse is ', scalar reverse $a;
can be
say 'Reverse is ' . reverse $a;
| [reply] [d/l] [select] |
Re: Python tricks
by markong (Pilgrim) on Dec 18, 2018 at 12:49 UTC
|
Going through the list reminded me the stressful feeling I had when I started playing with python trying to finish reading the official python tutorial...when I started experiencing indentation and unchecked variable names typos related bugs and had to tackle list comprehensions, I was reminded once again how (unfortunately) powerful is fashion/corporation's marketing in the CS field.
| [reply] |
|
|
I totally agree with you, I have the same experience. So sad.
| [reply] |
Re: Python tricks
by soonix (Chancellor) on Dec 18, 2018 at 12:55 UTC
|
(There's some duplication between items IX and X, and) my @r = <STDIN>;
will return whole lines as array element(s). You need my @r = split ' ', <STDIN>;
| [reply] [d/l] [select] |
|
|
You are right, we need the split.
| [reply] |
Re: Python tricks
by Eily (Monsignor) on Dec 18, 2018 at 14:21 UTC
|
print " ".join(a)
That's ugly :/ . This makes sense implementation-wise1, but I still2 hate the fact that join is method of the separator rather than the group of strings you join.
I got quite philosophical on that post xD
| [reply] [d/l] |
Re: Python tricks
by thechartist (Monk) on Mar 04, 2019 at 21:49 UTC
|
Done on Strawberry Perl 5.26.1
perl -MPDL -e "$seq = sequence(3,2)+1; print transpose( $seq );"
Edit: even better is:
perl -MPDL -e "print transpose(sequence(3,2)+1);"
The nested function calls appeal to my Lispy side; but in Perl, it is often easier for me to assign something to a variable, then pass that variable to a function/subroutine.
My matrix algebra is very rusty, but I suppose some of the other matrix problems have 1 line solutions using PDL. I will come back to this.
| [reply] [d/l] [select] |
|
|
I would highly recommend PDL::LinearAlgebra which has had a medium-sized update recently to get all the wrappers for the underlying LAPACK routines to work with "native complex" data. It turns perldl into a rather more MATLAB/Octave-like matrix tool.
| [reply] [d/l] |
Re: Python tricks
by parv (Parson) on Dec 18, 2018 at 13:08 UTC
|
Did your Perl solution to X cut off? Also, part of X is listed before IX (or, vice versa?).
Solutions to I, III-VII look same enough to me in both. Python 2 solution (untested) for IX:
# Is this not sufficient?
def is_anagram( A , B ):
return sorted( list( A ) ) == sorted( list( B ) )
| [reply] [d/l] |
Re: Python tricks
by rsFalse (Chaplain) on Mar 04, 2019 at 13:22 UTC
|
It is better to avoid using special variables '$a' and '$b'.
Use different name, e.g. '$_a', or longer meaningful name, or uppercase letter.
#!/usr/bin/perl -lw
use strict;
my ($a, $b) = (7, 5);
($b, $a) = ($a, $b);
print join ' ', sort { $a <=> $b } qw( 5 28 1 );
print "$b $a";
STDOUT:
5 1 28
7 5
STDERR:
"my $a" used in sort comparison at prog.pl line 8.
"my $b" used in sort comparison at prog.pl line 8.
I suggest to update examples with using of different names ;) | [reply] [d/l] [select] |
Re: Python tricks
by rsFalse (Chaplain) on Mar 04, 2019 at 13:38 UTC
|
On IX. Some variants with avoiding self repeating:
sub is_anagram {
my %hash;
map { $hash{ join '', sort split '' } ++ } @_;
return 2 > keys %hash ? 'True' : 'False';
}
sub is_anagram {
return qw( True False )[ eval join 'cmp', map "'$_'", map { join '
+', sort split '' } @_ ];
}
| [reply] [d/l] [select] |
|
|