Jump to content

Сравнение языков программирования (понимание списков)

Понимание списков — это синтаксическая конструкция, доступная в некоторых языках программирования для создания списка на основе существующих списков. Он следует форме математической нотации построителя множеств ( понимание множеств ), в отличие от использования функций карты и фильтра .

Примеры понимания списка

[ редактировать ]

Список со всеми дублями от 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 имеет встроенные функции 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 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;
$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))
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 ]
[ редактировать ]
Arc.Ask3.Ru: конец переведенного документа.
Arc.Ask3.Ru
Номер скриншота №: b24dd58f1704d31799c721677793c1c8__1700223960
URL1:https://arc.ask3.ru/arc/aa/b2/c8/b24dd58f1704d31799c721677793c1c8.html
Заголовок, (Title) документа по адресу, URL1:
Comparison of programming languages (list comprehension) - Wikipedia
Данный printscreen веб страницы (снимок веб страницы, скриншот веб страницы), визуально-программная копия документа расположенного по адресу URL1 и сохраненная в файл, имеет: квалифицированную, усовершенствованную (подтверждены: метки времени, валидность сертификата), открепленную ЭЦП (приложена к данному файлу), что может быть использовано для подтверждения содержания и факта существования документа в этот момент времени. Права на данный скриншот принадлежат администрации Ask3.ru, использование в качестве доказательства только с письменного разрешения правообладателя скриншота. Администрация Ask3.ru не несет ответственности за информацию размещенную на данном скриншоте. Права на прочие зарегистрированные элементы любого права, изображенные на снимках принадлежат их владельцам. Качество перевода предоставляется как есть. Любые претензии, иски не могут быть предъявлены. Если вы не согласны с любым пунктом перечисленным выше, вы не можете использовать данный сайт и информация размещенную на нем (сайте/странице), немедленно покиньте данный сайт. В случае нарушения любого пункта перечисленного выше, штраф 55! (Пятьдесят пять факториал, Денежную единицу (имеющую самостоятельную стоимость) можете выбрать самостоятельно, выплаичвается товарами в течение 7 дней с момента нарушения.)