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
Further information: Boo for .NET–Mono
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#
Further information: C# 3.0 Language Integrated Query
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
Further information: Ceylon, Ceylon comprehensions
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
Further information: List comprehension § 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
Further information: CoffeeScript
largeNumbers = (number for number in list when number > 100)Common Lisp
Further information: 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
Further information: Cobra
List the names of customers:
names = for cust in customers get cust.nameList the customers with balances:
names = for cust in customers where cust.balance > 0List the names of customers with balances:
names = for cust in customers where cust.balance > 0 get cust.nameThe general forms:
for VAR in ENUMERABLE [where CONDITION] get EXPR for VAR in ENUMERABLE where CONDITIONNote that by putting the condition and expression after the variable name and enumerable object, editors and IDEs can provide autocompletion on the members of the variable.
Dart
Further information: Dart, Dart lists
[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
Further information: Elixir
for x <- 0..100, x * x > 3, do: x * 2Erlang
Further information: Erlang
L = lists:seq(0,100). S = [2*X || X <- L, X*X > 3].F#
Further information: 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
Further information: 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
Further information: 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
Further information: 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
Further information: 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
Further information: 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) collectResultThe 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
Further information: OCaml
OCaml supports List comprehension through OCaml Batteries.2
Perl
Further information: 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
Further information: PowerShell
$s = ( 0..100 | ? {$_*$_ -gt 3} | % {2*$_} )which is short-hand notation of:
$s = 0..100 | where-object {$_*$_ -gt 3} | foreach-object {2*$_}Python
Further information: Python syntax and semantics § Comprehensions
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 lazy evaluation over its input, and can be used with generators to iterate over 'infinite' input such as the count generator function which returns successive integers:
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
Further information: R
x <- 0:100 S <- 2 * x[x ^ 2 > 3]Racket
Further information: 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
Further information: Raku (programming language)
my @s = ($_ * 2 if $_ ** 2 > 3 for 0 .. 99);Scala
Further information: Scala
Using the for-comprehension:
val s = for (x <- 0 to 100; if x*x > 3) yield 2*xScheme
Further information: 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
Further information: SETL
s := {2*x : x in {0..100} | x**2 > 3 };Smalltalk
Further information: Smalltalk
((1 to: 100) select: [ :x | x squared > 3 ]) collect: [ :x | x * 2 ]Visual Prolog
Further information: Visual Prolog
S = [ 2*X || X = list::getMember_nd(L), X*X > 3 ]External links
References
Nim sugar module https://nim-lang.github.io/Nim/sugar.html#collect.m%2Cuntyped%2Cuntyped ↩
OCaml Batteries Included http://batteries.forge.ocamlcore.org/ ↩
Scheme SRFI 42: Eager Comprehensions http://srfi.schemers.org/srfi-42/srfi-42.html ↩