Articulo de referencia

Comparación de lenguajes de programación (comprensión de listas)

La comprensión de listas es una construcción sintáctica disponible en algunos lenguajes de programación para crear listas a partir de listas existentes. Sigue la notación matemá...

La comprensión de listas es una construcción sintáctica disponible en algunos lenguajes de programación para crear listas a partir de listas existentes. Sigue la notación matemática de conjuntos ( comprensión de conjuntos ), a diferencia del uso de las funciones map y filter .

Ejemplos de comprensión de listas

Abucheo

Lista con todos los números dobles del 0 al 10 (exclusivos)

dobles = [ i * 2 para i en rango ( 10 )]

Lista con los nombres de los clientes con sede en Río de Janeiro.

rjCustomers = [ customer . Name for customer in customers if customer . State == "RJ" ]

C++

C++ puede utilizar el std::viewsespacio de nombres, introducido en C++20 .

using std :: vector ; using std :: ranges :: to ; using std :: views :: filter ; using std :: views :: transform ;vector < int > ns = std :: views :: iota ( 0 , 100 ) | filter ([]( int x ) -> bool { return x * x > 3 ; }) | transform ([]( int x ) -> int { return x * 2 ; }) | to < vector > ();

DO#

IEnumerable < int > ns = from x in Enumerable . Range ( 0 , 100 ) where x * x > 3 select x * 2 ;

El código anterior es azúcar sintáctico para el siguiente código escrito usando expresiones lambda:

IEnumerable < int > ns = Enumerable . Range ( 0 , 100 ) . Where ( x => x * x > 3 ) . Select ( x => x * 2 );

Ceilán

Filtrado de números divisibles por 3:

valor divisibleBy3 = { para ( i en 0 .. 100 ) si ( i % 3 == 0 ) i }; // el tipo de divisibleBy3 es Iterable<Integer>

Múltiples "generadores":

triples de valor = { para ( x en 0 .. 20 ) para ( y en x .. 20 ) para ( z en y .. 20 ) si ( x * x + y * y == z * z ) [ x , y , z ] }; // el tipo de triples es Iterable<Integer[3]>

Clojure

Una secuencia perezosa infinita:

( para [x ( iterar inc 0 ) :cuando ( > ( * x x ) 3 ) ] ( * 2 x ))

Una comprensión de lista que utiliza múltiples generadores:

( para [x ( rango 20 ) y ( rango 20 ) z ( rango 20 ) :cuando ( == ( + ( * x x ) ( * y y )) ( * z z )) ] [x y z] )

CoffeeScript

númerosgrandes = ( número para número en lista cuando número > 100 )

Lisp común

Las comprensiones de listas se pueden expresar con la palabra clave loopde la macro collect. Las condicionales se expresan con if, como sigue:

( bucle para x de 0 a 100 si ( > ( * x x ) 3 ) recolectar ( * 2 x ))

Cobra

Enumere los nombres de los clientes:

nombres = para cada cliente en clientes obtener cliente.nombre

Lista de clientes con saldos pendientes:

nombres = para cust en clientes donde cust.balance > 0

Enumere los nombres de los clientes con saldos pendientes:

nombres = para cust en clientes donde cust.balance > 0 obtener cust.nombre

Las formas generales:

para VAR en ENUMERABLE [ donde CONDICIÓN ] obtener EXPR para VAR en ENUMERABLE donde CONDICIÓN

Tenga en cuenta que, al colocar la condición y la expresión después del nombre de la variable y del objeto enumerable, los editores y los IDE pueden proporcionar autocompletado para los miembros de la variable.

Dardo

[ para ( var i en rango ( 0 , 100 )) si ( i * i > 3 ) i * 2 ]
var pyth = [ para ( var x en rango ( 1 , 20 )) para ( var y en rango ( x , 20 )) para ( var z en rango ( y , 20 )) si ( x * x + y * y == z * z ) [ x , y , z ] ];
Iterable < int > rango ( int inicio , int fin ) => Lista . generar ( fin - inicio , ( i ) => inicio + i );

Elixir

para x <- 0 .. 100 , x * x > 3 , hacer : x * 2

Erlang

L = listas : seq ( 0 , 100 ). S = [ 2 * X || X <- L , X * X > 3 ].

F#

Secuencias evaluadas de forma perezosa:

secuencia { para x en 0 .. 100 hacer si x * x > 3 entonces generar 2 * x }

O bien, para valores de punto flotante

secuencia { para x en 0 . .. 100 . hacer si x ** 2 . > 3 . entonces generar 2 .* x }

Listas y matrices:

[ para x en 0 . .. 100 . hacer si x ** 2 . > 3 . entonces generar 2 .* x ] [| para x en 0 . .. 100 . hacer si x ** 2 . > 3 . entonces generar 2 .* x |]

Las comprensiones de listas forman parte de una familia más amplia de construcciones lingüísticas llamadas expresiones de computación.

Haskell

[ x * 2 | x <- [ 0 .. 99 ], x * x > 3 ]

Un ejemplo de comprensión de lista que utiliza múltiples generadores:

pyth = [( x , y , z ) | x <- [ 1 .. 20 ], y <- [ x .. 20 ], z <- [ y .. 20 ], x ^ 2 + y ^ 2 == z ^ 2 ]

Yo

Mediante el uso del objeto Range, el lenguaje Io puede crear listas con la misma facilidad que en otros lenguajes:

Rango 0 a ( 100 ) como lista seleccionar ( x , x * x > 3 ) mapear (* 2 )

ISLISP

Las comprensiones de listas se pueden expresar con la forforma especial. Las condicionales se expresan con if, como sigue:

( para (( x 0 ( + x 1 )) ( recolectar ())) (( >= x 100 ) ( recolectar inversamente )) ( si ( > ( * x x ) 3 ) ( establecer recolectar ( cons ( * x 2 ) recolectar ))))

Julia

Julia admite comprensiones utilizando la siguiente sintaxis:

y = [ x ^ 2 + 1 para x en 1 : 10 ]

y comprensiones multidimensionales como:

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

También es posible añadir una condición:

v = [ 3 x ^ 2 + 2 y ^ 2 para x en 1 : 7 para y en 1 : 7 si x % y == 0 ]

Y simplemente cambiando los corchetes cuadrados por los redondos, obtenemos un generador:

g = ( 3 x ^ 2 + 2 y ^ 2 para x en 1 : 7 para y en 1 : 7 si x % y == 0 )

Mitrilo

s = [ 2*i para i en 1..100 donde i*i > 3 ];

Generadores múltiples:

pyth = [ (x,y,z) para x en 1..20 para y en x..20 para z en y..20 donde x*x + y*y == z*z ];

Nemerle

$[ x * 2 | x en [ 0 .. 100 ], x * x > 3 ]

Nim

Nim tiene comprensiones de secuencia, conjunto, tabla y objeto incorporadas en el módulo de biblioteca estándar sugar: [ 1 ]

importar azúcarlet variable = collect ( newSeq ): for item in @[- 9 , 1 , 42 , 0 , - 1 , 9 ] : item + 1afirmar variable == @[- 8 , 2 , 43 , 1 , 0 , 10 ]

La comprensión se implementa como una macro que se expande en tiempo de compilación; puede ver el código expandido utilizando la opción de compilador expandMacro :

var collectResult = newSeq ( Natural ( 0 )) for item in items ( @[- 9 , 1 , 42 , 0 , - 1 , 9 ] ): add ( collectResult , item + 1 ) collectResult

Las comprensiones pueden estar anidadas y ser de varias líneas:

importar azúcarlet 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 admite la comprensión de listas a través de OCaml Batteries . [ 2 ]

Perl

mi @s = map { 2 * $_ } grep { $_ ** 2 > 3 } 0 .. 99 ;

Arreglo con todos los números dobles del 1 al 9 inclusive:

mis @doubles = map { $_ * 2 } 1 .. 9 ;

Arreglo con los nombres de los clientes con sede en Río de Janeiro (a partir de un arreglo de hashes):

mi @rjCustomers = map { $_ -> { estado } eq "RJ" ? $_ -> { nombre } : ()} @customers ;

Filtrado de números divisibles por 3:

mi @divisibleBy3 = grep { $_ % 3 == 0 } 0 .. 100 ;

PowerShell

$s = ( 0 .. 100 | ? { $_ * $_ -gt 3 } | % { 2 * $_ } )

que es una notación abreviada de:

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

Pitón

Python utiliza la siguiente sintaxis para expresar comprensiones de listas sobre listas finitas:

s : lista [ int ] = [ 2 * x para x en rango ( 100 ) si x ** 2 > 3 ]

En las versiones de Python >= 2.4 se puede utilizar una expresión generadora que proporciona una evaluación perezosa sobre su entrada, y se puede utilizar con generadores para iterar sobre una entrada 'infinita', como la función generadora count que devuelve enteros sucesivos:

import itertools from typing import Iterators : Iterador [ int ] = ( 2 * x para x en itertools.count ( ) si x ** 2 > 3 )

(El uso posterior de la expresión generadora determinará cuándo dejar de generar valores).

R

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

Raqueta

( para/lista ([ x 100 ] #:cuando ( > ( * x x ) 3 )) ( * x 2 ))

Un ejemplo con múltiples generadores:

( para*/lista ([ x ( en rango 1 21 )] [ y ( en rango 1 21 )] [ z ( en rango 1 21 )] #:cuando ( = ( + ( * x x ) ( * y y )) ( * z z ))) ( lista x y z ))

Raku

mis @s = ( $_ * 2 si $_ ** 2 > 3 para 0 .. 99 ); 

Scala

Utilizando la comprensión:

val s = para ( x <- 0 a 100 ; si x * x > 3 ) generar 2 * x

Esquema

Las comprensiones de listas son compatibles en Scheme mediante el uso de la biblioteca SRFI -42. [ 3 ]

( lista-ec ( : x 100 ) ( si ( > ( * x x ) 3 )) ( * x 2 ))

Un ejemplo de comprensión de lista que utiliza múltiples generadores:

( lista-ec ( : x 1 21 ) ( : y x ​​21 ) ( : z y 21 ) ( si ( = ( + ( * x x ) ( * y y )) ( * z z ))) ( lista x y z ))

SETL

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

Charla informal

(( 1 a: 100 ) seleccionar: [ : x | x al cuadrado > 3 ]) recopilar: [ : x | x * 2 ] 

Prólogo visual

S = [ 2 * X || X = lista::obtener_miembro_nd ( L ) , X * X > 3 ]

Referencias

  1. Módulo de azúcar Nim
  2. Baterías OCaml incluidas
  3. Esquema SRFI 42: Comprensiones entusiastas