Comparison of programming languages (list comprehension)
This article needs additional citations for verification. (February 2009) |
Comparison of programming languages |
---|
|
Comparison of individual languages
|
List comprehension is a syntactic construct available in some programming languages for creating a list based on existing lists. It follows the form of the mathematical set-builder notation (set comprehension) as distinct from the use of map and filter functions.
Examples of list comprehension
Boo
List with all the doubles from 0 to 10 (exclusive)
doubles = [i*2 for i in range(10)]
List with the names of the customers based in Rio de Janeiro
rjCustomers = [customer.Name for customer in customers if customer.State == "RJ"]
C#
var ns = from x in Enumerable.Range(0, 100)
where x * x > 3
select x * 2;
The previous code is syntactic sugar for the following code written using lambda expressions:
var ns = Enumerable.Range(0, 100)
.Where(x => x * x > 3)
.Select(x => x * 2);
Ceylon
Filtering numbers divisible by 3:
value divisibleBy3 = { for (i in 0..100) if (i%3==0) i };
// type of divisibleBy3 is Iterable<Integer>
Multiple "generators":
value triples = { for (x in 0..20) for (y in x..20) for (z in y..20) if (x*x + y*y == z*z) [x,y,z] };
// type of triples is Iterable<Integer[3]>
Clojure
An infinite lazy sequence:
(for [x (iterate inc 0)
:when (> (* x x) 3)]
(* 2 x))
A list comprehension using multiple generators:
(for [x (range 20)
y (range 20)
z (range 20)
:when (== (+ (* x x) (* y y)) (* z z))]
[x y z])
CoffeeScript
largeNumbers = (number for number in list when number > 100)
Common Lisp
List comprehensions can be expressed with the loop
macro's collect
keyword. Conditionals are expressed with if
, as follows:
(loop for x from 0 to 100 if (> (* x x) 3) collect (* 2 x))
Cobra
List the names of customers:
names = for cust in customers get cust.name
List the customers with balances:
names = for cust in customers where cust.balance > 0
List the names of customers with balances:
names = for cust in customers where cust.balance > 0 get cust.name
The general forms:
for VAR in ENUMERABLE [where CONDITION] get EXPR
for VAR in ENUMERABLE where CONDITION
Note that by putting the condition and expression after the variable name and enumerable object, editors and IDEs can provide
Dart
[for (var i in range(0, 100)) if (i * i > 3) i * 2]
var pyth = [
for (var x in range(1, 20))
for (var y in range(x, 20))
for (var z in range(y, 20)) if (x * x + y * y == z * z) [x, y, z]
];
Iterable<int> range(int start, int end) =>
List.generate(end - start, (i) => start + i);
Elixir
for x <- 0..100, x * x > 3, do: x * 2
Erlang
L = lists:seq(0,100).
S = [2*X || X <- L, X*X > 3].
F#
Lazily-evaluated sequences:
seq { for x in 0 .. 100 do if x*x > 3 then yield 2*x }
Or, for floating point values
seq { for x in 0. .. 100. do if x**2. > 3. then yield 2.*x }
Lists and arrays:
[ for x in 0. .. 100. do if x**2. > 3. then yield 2.*x ]
[| for x in 0. .. 100. do if x**2. > 3. then yield 2.*x |]
List comprehensions are the part of a greater family of language constructs called computation expressions.
Haskell
[x * 2 | x <- [0 .. 99], x * x > 3]
An example of a list comprehension using multiple generators:
pyth = [(x,y,z) | x <- [1..20], y <- [x..20], z <- [y..20], x^2 + y^2 == z^2]
Io
By using Range object, Io language can create list as easy as in other languages:
Range 0 to(100) asList select(x, x*x>3) map(*2)
ISLISP
List comprehensions can be expressed with the for
special form. Conditionals are expressed with if
, as follows:
(for ((x 0 (+ x 1))
(collect ()))
((>= x 100) (reverse collect))
(if (> (* x x) 3)
(setq collect (cons (* x 2) collect))))
Julia
Julia supports comprehensions using the syntax:
y = [x^2+1 for x in 1:10]
and multidimensional comprehensions like:
z = [(x-5)^2+(y-5)^2 for x = 0:10, y = 0:10]
It is also possible to add a condition:
v = [3x^2 + 2y^2 for x in 1:7 for y in 1:7 if x % y == 0]
And just changing square brackets to the round one, we get a generator:
g = (3x^2 + 2y^2 for x in 1:7 for y in 1:7 if x % y == 0)
Mythryl
s = [ 2*i for i in 1..100 where i*i > 3 ];
Multiple generators:
pyth = [ (x,y,z) for x in 1..20 for y in x..20 for z in y..20 where x*x + y*y == z*z ];
Nemerle
$[x*2 | x in [0 .. 100], x*x > 3]
Nim
Nim has built-in seq, set, table and object comprehensions on the sugar standard library module:[1]
import sugar
let variable = collect(newSeq):
for item in @[-9, 1, 42, 0, -1, 9]: item + 1
assert variable == @[-8, 2, 43, 1, 0, 10]
The comprehension is implemented as a macro that is expanded at compile time, you can see the expanded code using the expandMacro compiler option:
var collectResult = newSeq(Natural(0))
for item in items(@[-9, 1, 42, 0, -1, 9]):
add(collectResult, item + 1)
collectResult
The comprehensions can be nested and multi-line:
import sugar
let values = collect(newSeq):
for val in [1, 2]:
collect(newSeq):
for val2 in [3, 4]:
if (val, val2) != (1, 2):
(val, val2)
assert values == @[@[(1, 3), (1, 4)], @[(2, 3), (2, 4)]]
OCaml
OCaml supports List comprehension through OCaml Batteries.[2]
Perl
my @s = map {2 * $_} grep {$_ ** 2 > 3} 0..99;
Array with all the doubles from 1 to 9 inclusive:
my @doubles = map {$_ * 2} 1..9;
Array with the names of the customers based in Rio de Janeiro (from array of hashes):
my @rjCustomers = map {$_->{state} eq "RJ" ? $_->{name} : ()} @customers;
Filtering numbers divisible by 3:
my @divisibleBy3 = grep {$_ % 3 == 0} 0..100;
PowerShell
$s = ( 0..100 | ? {$_*$_ -gt 3} | % {2*$_} )
which is short-hand notation of:
$s = 0..100 | where-object {$_*$_ -gt 3} | foreach-object {2*$_}
Python
Python uses the following syntax to express list comprehensions over finite lists:
S = [2 * x for x in range(100) if x ** 2 > 3]
A generator expression may be used in Python versions >= 2.4 which gives
from itertools import count
S = (2 * x for x in count() if x ** 2 > 3)
(Subsequent use of the generator expression will determine when to stop generating values).
R
x <- 0:100
S <- 2 * x[x ^ 2 > 3]
Racket
(for/list ([x 100] #:when (> (* x x) 3)) (* x 2))
An example with multiple generators:
(for*/list ([x (in-range 1 21)] [y (in-range 1 21)] [z (in-range 1 21)]
#:when (= (+ (* x x) (* y y)) (* z z)))
(list x y z))
Raku
my @s = ($_ * 2 if $_ ** 2 > 3 for 0 .. 99);
Scala
Using the for-comprehension:
val s = for (x <- 0 to 100; if x*x > 3) yield 2*x
Scheme
List comprehensions are supported in Scheme through the use of the SRFI-42 library.[3]
(list-ec (: x 100) (if (> (* x x) 3)) (* x 2))
An example of a list comprehension using multiple generators:
(list-ec (: x 1 21) (: y x 21) (: z y 21) (if (= (+ (* x x) (* y y)) (* z z))) (list x y z))
SETL
s := {2*x : x in {0..100} | x**2 > 3 };
Smalltalk
((1 to: 100) select: [ :x | x squared > 3 ]) collect: [ :x | x * 2 ]
Visual Prolog
S = [ 2*X || X = list::getMember_nd(L), X*X > 3 ]