2005-02-11
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.)
Reference: Mathematica Ref: Table↗.
Reference: Python Doc↗.
Perl the language does not have the “list comprehension” per se. (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 far more powerful than the so-called “list comprehension”. For a perl version of Mathematica's Table: See http://xahlee.org/tree/Table.html
See also:
Page created: 2005-02. © 2005 by Xah Lee.