List Comprehension in Python and Perl

Advertise Here

,

Python

David Eppstein of the Geometry Junkyard fame gave this elegant version for returning all possible pairs from a range of n numbers.

def combo2(n):
    return dict([('%d,%d'%(i,j),(i,j)) for j in range(1,n+1) for i in range(1,j)])

print combo2(3) # prints
# {'3,4': (3, 4), '1,4': (1, 4), '1,2': (1, 2), '1,3': (1, 3), '2,4': (2, 4), '2,3': (2, 3)}

This construct uses a irregular syntax (called “list comprehension”) to generate a expression normally built by nested loops. This construct has acquired a incomprehensible name “list comprehension” in computing industry and academia.

In Python, this syntax irregularity works like this, for example, generating a list of i*2 with i from 1 to 5:

myList = [ i*2 for i in range(1,6)]
print myList

Another example: To built a list of couples of the form (i*2,i*3):

myList = [ (i*2,i*3) for i in range(1,6)]
print myList

In general this expression generating syntax has the form “[‹expression› ‹iteration›]” where the “‹expression›” contains some variables in “‹iteration›” , and the result of each loop is put into a list.

The iteration part can be nested. Example:

# python

myList = [ (i,j) for i in range(1,6) for j in range(1,4)]
print myList
# prints [(1, 1), (1, 2), (1, 3), (2, 1), (2, 2), (2, 3), (3, 1), (3,
# 2), (3, 3), (4, 1), (4, 2), (4, 3), (5, 1), (5, 2), (5, 3)]

Remember, this jargonized “list comprehension” is nothing more than a irregular syntax for building a list from loops. Its purpose is purely of syntactical convenience. Advanced languages such as functional languages often have this power without the syntax irregularity. (For example, Mathematica's Table function.)

Perl

Perl the language does not have the “list comprehension” as it is. However, in general, functional programing's brevity is more easily achieved in perl than python.

Here's a example of generating a list of i*2 for i from 1 to 5:

# perl
@myList = map {$_ * 2} (1..5);

use Data::Dumper;
print Dumper(\@myList);

Here's a example of generating a list of pairs “[i*2,i*3]”.

# perl
@myList = map {[$_ * 2, $_ * 3]} (1..5);

use Data::Dumper;
print Dumper(\@myList);

Here's a example of generating a nested list involving 2 looping variables that's normally done with “list comprehension”. In perl, it's just done with normal nested loops.

# perl
@myList=();
for ($i=1;$i<=5;$i++) {
  for ($j=1;$j<=3;$j++) {
    push (@myList, [$i,$j]);
  }
}

use Data::Dumper; $Data::Dumper::Indent=0;
print Dumper(\@myList);

# prints $VAR1 = [[1,1],[1,2],[1,3],[2,1],[2,2],[2,3],
# [3,1],[3,2],[3,3],[4,1],[4,2],[4,3],[5,1],[5,2],[5,3]];

Note: Mathematica's Table function is a list generator and is much more powerful than the so-called “list comprehension”. For a perl version of Mathematica's Table, see: Tree Functions: Table.

blog comments powered by Disqus