Сравнение языков программирования (понимание списков)
Эта статья нуждается в дополнительных цитатах для проверки . ( февраль 2009 г. ) |
Понимание списков — это синтаксическая конструкция, доступная в некоторых языках программирования для создания списка на основе существующих списков. Он следует форме математической нотации построителя множеств ( понимание множеств ), в отличие от использования функций карты и фильтра .
Примеры понимания списка
[ редактировать ]Бу
[ редактировать ]Список со всеми дублями от 0 до 10 (эксклюзивно)
doubles = [i*2 for i in range(10)]
Список с именами клиентов из Рио-де-Жанейро.
rjCustomers = [customer.Name for customer in customers if customer.State == "RJ"]
С#
[ редактировать ]var ns = from x in Enumerable.Range(0, 100)
where x * x > 3
select x * 2;
Предыдущий код является синтаксическим сахаром для следующего кода, написанного с использованием лямбда-выражений:
var ns = Enumerable.Range(0, 100)
.Where(x => x * x > 3)
.Select(x => x * 2);
Цейлон
[ редактировать ]Фильтрация чисел, кратных 3:
value divisibleBy3 = { for (i in 0..100) if (i%3==0) i };
// type of divisibleBy3 is Iterable<Integer>
Несколько «генераторов»:
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]>
Кложур
[ редактировать ]Бесконечная ленивая последовательность:
(for [x (iterate inc 0)
:when (> (* x x) 3)]
(* 2 x))
Понимание списка с использованием нескольких генераторов:
(for [x (range 20)
y (range 20)
z (range 20)
:when (== (+ (* x x) (* y y)) (* z z))]
[x y z])
Кофескрипт
[ редактировать ]largeNumbers = (number for number in list when number > 100)
Общий Лисп
[ редактировать ]Понимание списков может быть выражено с помощью loop
макросы collect
ключевое слово. Условные обозначения выражаются с помощью if
, следующее:
(loop for x from 0 to 100 if (> (* x x) 3) collect (* 2 x))
Кобра
[ редактировать ]Перечислите имена клиентов:
names = for cust in customers get cust.name
Перечислите клиентов с остатками:
names = for cust in customers where cust.balance > 0
Перечислите имена клиентов с остатками:
names = for cust in customers where cust.balance > 0 get cust.name
Общие формы:
for VAR in ENUMERABLE [where CONDITION] get EXPR
for VAR in ENUMERABLE where CONDITION
Обратите внимание: помещая условие и выражение после имени переменной и перечисляемого объекта, редакторы и IDE могут обеспечить автодополнение для членов переменной.
Дарт
[ редактировать ][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);
Эликсир
[ редактировать ]for x <- 0..100, x * x > 3, do: x * 2
Эрланг
[ редактировать ]L = lists:seq(0,100).
S = [2*X || X <- L, X*X > 3].
Ф#
[ редактировать ]Лениво вычисляемые последовательности:
seq { for x in 0 .. 100 do if x*x > 3 then yield 2*x }
Или для значений с плавающей запятой
seq { 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 ]
[| for x in 0. .. 100. do if x**2. > 3. then yield 2.*x |]
Понимания списков являются частью большого семейства языковых конструкций, называемых вычислительными выражениями.
Хаскелл
[ редактировать ][x * 2 | x <- [0 .. 99], x * x > 3]
Пример понимания списка с использованием нескольких генераторов:
pyth = [(x,y,z) | x <- [1..20], y <- [x..20], z <- [y..20], x^2 + y^2 == z^2]
Этот
[ редактировать ]Используя объект Range, язык Io может создавать списки так же легко, как и в других языках:
Range 0 to(100) asList select(x, x*x>3) map(*2)
ИСЛИСП
[ редактировать ]Понимание списков может быть выражено с помощью for
особая форма. Условные обозначения выражаются с помощью if
, следующее:
(for ((x 0 (+ x 1))
(collect ()))
((>= x 100) (reverse collect))
(if (> (* x x) 3)
(setq collect (cons (* x 2) collect))))
Юлия
[ редактировать ]Julia поддерживает понимание, используя синтаксис:
y = [x^2+1 for x in 1:10]
и многомерные понимания, такие как:
z = [(x-5)^2+(y-5)^2 for x = 0:10, y = 0:10]
Также можно добавить условие:
v = [3x^2 + 2y^2 for x in 1:7 for y in 1:7 if x % y == 0]
И просто заменив квадратные скобки на круглые, получим генератор:
g = (3x^2 + 2y^2 for x in 1:7 for y in 1:7 if x % y == 0)
Миф
[ редактировать ]s = [ 2*i for i in 1..100 where i*i > 3 ];
Несколько генераторов:
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 ];
Немерль
[ редактировать ]$[x*2 | x in [0 .. 100], x*x > 3]
Nim
[ редактировать ]Nim имеет встроенные функции seq, set, table и object в модуле стандартной библиотеки сахара: [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]
Понимание реализовано в виде макроса, который расширяется во время компиляции. вы можете увидеть расширенный код, используя опцию компилятораexpandMacro :
var collectResult = newSeq(Natural(0))
for item in items(@[-9, 1, 42, 0, -1, 9]):
add(collectResult, item + 1)
collectResult
Понимания могут быть вложенными и многострочными:
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 поддерживает понимание списков через OCaml Batteries . [2]
Перл
[ редактировать ]my @s = map {2 * $_} grep {$_ ** 2 > 3} 0..99;
Массив со всеми дублями от 1 до 9 включительно:
my @doubles = map {$_ * 2} 1..9;
Массив с именами клиентов из Рио-де-Жанейро (из массива хешей):
my @rjCustomers = map {$_->{state} eq "RJ" ? $_->{name} : ()} @customers;
Фильтрация чисел, кратных 3:
my @divisibleBy3 = grep {$_ % 3 == 0} 0..100;
PowerShell
[ редактировать ]$s = ( 0..100 | ? {$_*$_ -gt 3} | % {2*$_} )
что является сокращенной записью:
$s = 0..100 | where-object {$_*$_ -gt 3} | foreach-object {2*$_}
Питон
[ редактировать ]Python использует следующий синтаксис для выражения понимания списков в конечных списках:
S = [2 * x for x in range(100) if x ** 2 > 3]
Выражение генератора может использоваться в версиях Python >= 2.4, которое дает ленивую оценку входных данных, и может использоваться с генераторами для перебора «бесконечных» входных данных, таких как функция генератора счетчика, которая возвращает последовательные целые числа:
from itertools import count
S = (2 * x for x in count() if x ** 2 > 3)
(Последующее использование выражения-генератора определит, когда прекратить генерирование значений).
Р
[ редактировать ] x <- 0:100
S <- 2 * x[x ^ 2 > 3]
Ракетка
[ редактировать ](for/list ([x 100] #:when (> (* x x) 3)) (* x 2))
Пример с несколькими генераторами:
(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))
Раку
[ редактировать ] my @s = ($_ * 2 if $_ ** 2 > 3 for 0 .. 99);
Скала
[ редактировать ]Использование понимания:
val s = for (x <- 0 to 100; if x*x > 3) yield 2*x
Схема
[ редактировать ]Понимание списков поддерживается в Scheme за счет использования библиотеки SRFI -42. [3]
(list-ec (: x 100) (if (> (* x x) 3)) (* x 2))
Пример понимания списка с использованием нескольких генераторов:
(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 };
Смолток
[ редактировать ]((1 to: 100) select: [ :x | x squared > 3 ]) collect: [ :x | x * 2 ]
Визуальный Пролог
[ редактировать ]S = [ 2*X || X = list::getMember_nd(L), X*X > 3 ]