Comparison of programming languages (list comprehension)

Last updated

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.

Contents

Examples of list comprehension

Boo

List with all the doubles from 0 to 10 (exclusive)

doubles=[i*2foriinrange(10)]

List with the names of the customers based in Rio de Janeiro

rjCustomers=[customer.Nameforcustomerincustomersifcustomer.State=="RJ"]

C#

varns=fromxinEnumerable.Range(0,100)wherex*x>3selectx*2;

The previous code is syntactic sugar for the following code written using lambda expressions:

varns=Enumerable.Range(0,100).Where(x=>x*x>3).Select(x=>x*2);

Ceylon

Filtering numbers divisible by 3:

valuedivisibleBy3={for(iin0..100)if(i%3==0)i};// type of divisibleBy3 is Iterable<Integer>

Multiple "generators":

valuetriples={for(xin0..20)for(yinx..20)for(ziny..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(iterateinc0):when(>(*xx)3)](*2x))

A list comprehension using multiple generators:

(for[x(range20)y(range20)z(range20):when(==(+(*xx)(*yy))(*zz))][xyz])

CoffeeScript

largeNumbers=(numberfornumberinlistwhennumber>100)

Common Lisp

List comprehensions can be expressed with the loop macro's collect keyword. Conditionals are expressed with if, as follows:

(loopforxfrom0to100if(>(*xx)3)collect(*2x))

Cobra

List the names of customers:

names=forcustincustomersgetcust.name

List the customers with balances:

names=forcustincustomerswherecust.balance>0

List the names of customers with balances:

names=forcustincustomerswherecust.balance>0getcust.name

The general forms:

forVARinENUMERABLE[whereCONDITION]getEXPRforVARinENUMERABLEwhereCONDITION

Note 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

[for(variinrange(0,100))if(i*i>3)i*2]
varpyth=[for(varxinrange(1,20))for(varyinrange(x,20))for(varzinrange(y,20))if(x*x+y*y==z*z)[x,y,z]];
Iterable<int>range(intstart,intend)=>List.generate(end-start,(i)=>start+i);

Elixir

forx<-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{forxin0..100doifx*x>3thenyield2*x}

Or, for floating point values

seq{forxin0...100.doifx**2.>3.thenyield2.*x}

Lists and arrays:

[forxin0...100.doifx**2.>3.thenyield2.*x][|forxin0...100.doifx**2.>3.thenyield2.*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:

Range0to(100)asListselect(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((x0(+x1))(collect()))((>=x100)(reversecollect))(if(>(*xx)3)(setqcollect(cons(*x2)collect))))


Julia

Julia supports comprehensions using the syntax:

y=[x^2+1forxin1:10]

and multidimensional comprehensions like:

z=[(x-5)^2+(y-5)^2forx=0:10,y=0:10]

It is also possible to add a condition:

v=[3x^2+2y^2forxin1:7foryin1:7ifx%y==0]

And just changing square brackets to the round one, we get a generator:

g=(3x^2+2y^2forxin1:7foryin1:7ifx%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|xin[0..100],x*x>3]

Nim

Nim has built-in seq, set, table and object comprehensions on the sugar standard library module: [1]

importsugarletvariable=collect(newSeq):foritemin@[-9,1,42,0,-1,9]:item+1assertvariable==@[-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:

varcollectResult=newSeq(Natural(0))foriteminitems(@[-9,1,42,0,-1,9]):add(collectResult,item+1)collectResult

The comprehensions can be nested and multi-line:

importsugarletvalues=collect(newSeq):forvalin[1,2]:collect(newSeq):forval2in[3,4]:if(val,val2)!=(1,2):(val,val2)assertvalues==@[@[(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|?{$_*$_-gt3}|%{2*$_})

which is short-hand notation of:

$s=0..100|where-object{$_*$_-gt3}|foreach-object{2*$_}

Python

Python uses the following syntax to express list comprehensions over finite lists:

S=[2*xforxinrange(100)ifx**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:

fromitertoolsimportcountS=(2*xforxincount()ifx**2>3)

(Subsequent use of the generator expression will determine when to stop generating values).

R

x<-0:100S<-2*x[x^2>3]

Racket

(for/list([x100]#:when(>(*xx)3))(*x2))

An example with multiple generators:

(for*/list([x(in-range121)][y(in-range121)][z(in-range121)]#:when(=(+(*xx)(*yy))(*zz)))(listxyz))

Raku

my@s = ($_ * 2if$_ ** 2 > 3for0 .. 99); 

Scala

Using the for-comprehension:

vals=for(x<-0to100;ifx*x>3)yield2*x

Scheme

List comprehensions are supported in Scheme through the use of the SRFI-42 library. [3]

(list-ec(:x100)(if(>(*xx)3))(*x2))

An example of a list comprehension using multiple generators:

(list-ec(:x121)(:yx21)(:zy21)(if(=(+(*xx)(*yy))(*zz)))(listxyz))

SETL

s := {2*x : x in {0..100} | x**2 > 3 }; 

Smalltalk

((1to:100) select: [ :x|xsquared>3 ]) collect: [ :x|x*2 ] 

Visual Prolog

S = [2*X||X = list::getMember_nd(L), X*X>3]

References