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]

Related Research Articles

In programming language theory, lazy evaluation, or call-by-need, is an evaluation strategy which delays the evaluation of an expression until its value is needed and which also avoids repeated evaluations.

<span class="mw-page-title-main">Linear congruential generator</span> Algorithm for generating pseudo-randomized numbers

A linear congruential generator (LCG) is an algorithm that yields a sequence of pseudo-randomized numbers calculated with a discontinuous piecewise linear equation. The method represents one of the oldest and best-known pseudorandom number generator algorithms. The theory behind them is relatively easy to understand, and they are easily implemented and fast, especially on computer hardware which can provide modular arithmetic by storage-bit truncation.

The Mersenne Twister is a general-purpose pseudorandom number generator (PRNG) developed in 1997 by Makoto Matsumoto and Takuji Nishimura. Its name derives from the fact that its period length is chosen to be a Mersenne prime.

In mathematics, specifically ring theory, a principal ideal is an ideal in a ring that is generated by a single element of through multiplication by every element of The term also has another, similar meaning in order theory, where it refers to an (order) ideal in a poset generated by a single element which is to say the set of all elements less than or equal to in

In set theory and its applications to logic, mathematics, and computer science, set-builder notation is a mathematical notation for describing a set by enumerating its elements, or stating the properties that its members must satisfy.

<span class="mw-page-title-main">F Sharp (programming language)</span> Microsoft programming language

F# is a functional-first, general-purpose, strongly typed, multi-paradigm programming language that encompasses functional, imperative, and object-oriented programming methods. It is most often used as a cross-platform Common Language Infrastructure (CLI) language on .NET, but can also generate JavaScript and graphics processing unit (GPU) code.

A 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 as distinct from the use of map and filter functions.

In computability theory, a set S of natural numbers is called computably enumerable (c.e.), recursively enumerable (r.e.), semidecidable, partially decidable, listable, provable or Turing-recognizable if:

In computer science, a generator is a routine that can be used to control the iteration behaviour of a loop. All generators are also iterators. A generator is very similar to a function that returns an array, in that a generator has parameters, can be called, and generates a sequence of values. However, instead of building an array containing all the values and returning them all at once, a generator yields the values one at a time, which requires less memory and allows the caller to get started processing the first few values immediately. In short, a generator looks like a function but behaves like an iterator.

<span class="mw-page-title-main">Foreach loop</span> Control flow statement for traversing items in a collection

In computer programming, foreach loop is a control flow statement for traversing items in a collection. foreach is usually used in place of a standard for loop statement. Unlike other for loop constructs, however, foreach loops usually maintain no explicit counter: they essentially say "do this to everything in this set", rather than "do this x times". This avoids potential off-by-one errors and makes code simpler to read. In object-oriented languages, an iterator, even if implicit, is often used as the means of traversal.

In modular arithmetic computation, Montgomery modular multiplication, more commonly referred to as Montgomery multiplication, is a method for performing fast modular multiplication. It was introduced in 1985 by the American mathematician Peter L. Montgomery.

In probability theory, a compound Poisson distribution is the probability distribution of the sum of a number of independent identically-distributed random variables, where the number of terms to be added is itself a Poisson-distributed variable. The result can be either a continuous or a discrete distribution.

<span class="mw-page-title-main">JavaScript syntax</span> Set of rules defining correctly structured programs

The syntax of JavaScript is the set of rules that define a correctly structured JavaScript program.

<span class="mw-page-title-main">Burning Ship fractal</span> Complex plane fractal

The Burning Ship fractal, first described and created by Michael Michelitsch and Otto E. Rössler in 1992, is generated by iterating the function:

<span class="mw-page-title-main">Python syntax and semantics</span> Set of rules defining correctly structured programs

The syntax of the Python programming language is the set of rules that defines how a Python program will be written and interpreted. The Python language has many similarities to Perl, C, and Java. However, there are some definite differences between the languages. It supports multiple programming paradigms, including structured, object-oriented programming, and functional programming, and boasts a dynamic type system and automatic memory management.

The syntax and semantics of PHP, a programming language, form a set of rules that define how a PHP program can be written and interpreted.

In mathematics, Birkhoff's representation theorem for distributive lattices states that the elements of any finite distributive lattice can be represented as finite sets, in such a way that the lattice operations correspond to unions and intersections of sets. The theorem can be interpreted as providing a one-to-one correspondence between distributive lattices and partial orders, between quasi-ordinal knowledge spaces and preorders, or between finite topological spaces and preorders. It is named after Garrett Birkhoff, who published a proof of it in 1937.

The syntax and semantics of Prolog, a programming language, are the sets of rules that define how a Prolog program is written and how it is interpreted, respectively. The rules are laid out in ISO standard ISO/IEC 13211 although there are differences in the Prolog implementations.

<span class="mw-page-title-main">PascalABC.NET</span> Computer programming language

PascalABC.NET is a high-level general-purpose programming language supporting multiple paradigms. PascalABC.NET is based on Delphi's Object Pascal, but also has influences from C#, Python, Kotlin and Haskell. It is distributed both as a command-line tool for Windows, Linux and MacOS (Mono), and with an integrated development environment for Windows and Linux, including interactive debugger, IntelliSense system, form designer, code templates and code auto-formatting.

References