Понимание списка - это синтаксическая конструкция, доступная в некоторых языках программирования для создания списка на основе существующих списков. Он следует форме математической нотации построителя множеств ( понимание множества ) в отличие от использования функций карты и фильтра .
Примеры понимания списка
Бу
Список со всеми двойными числами от 0 до 10 (исключая)
doubles = [ i * 2 for i in range ( 10 )]
Список с именами клиентов из Рио-де-Жанейро
rjCustomers = [ покупатель . Имя для клиента в клиентах , если клиент . State == "RJ" ]
C #
var ns = from x в Enumerable . Диапазон ( 0 , 100 ), где x * x > 3 выберите x * 2 ;
Предыдущий код является синтаксическим сахаром для следующего кода, написанного с использованием лямбда-выражений:
var ns = Перечислимый . Диапазон ( 0 , 100 ) . Где ( x => x * x > 3 ) . Выберите ( x => x * 2 );
Цейлон
Фильтрация чисел, кратных 3:
значение divisibleBy3 = { for ( i in 0 .. 100 ) if ( i % 3 == 0 ) i }; // тип divisibleBy3 - Iterable
Множественные «генераторы»:
тройка значений = { 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 ] }; // тип троек - Iterable
Clojure
Бесконечная ленивая последовательность:
( для [x ( итерация inc 0 ) : when ( > ( * x x ) 3 ) ] ( * 2 x ))
Понимание списка с использованием нескольких генераторов:
( для [x ( диапазон 20 ) y ( диапазон 20 ) z ( диапазон 20 ) : when ( == ( + ( * x x ) ( * y y )) ( * z z )) ] [x y z] )
CoffeeScript
largeNumbers = ( число для числа в списке, если число > 100 )
Common Lisp
Понимание списка может быть выражено с помощью ключевого слова loop
макроса collect
. Условные выражения выражаются if
следующим образом:
( цикл для x от 0 до 100 if ( > ( * x x ) 3 ) collect ( * 2 x ))
Кобра
Перечислите имена клиентов:
Имена = для Каст в клиентах получить касты . название
Перечислите клиентов с остатками:
names = для cust в клиентах, где cust . баланс > 0
Перечислите имена клиентов с остатками:
names = для cust в клиентах, где cust . баланс > 0 получить cust . название
Общие формы:
для VAR в ENUMERABLE [ где CONDITION ] получить EXPR для VAR в ENUMERABLE, где 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 ] ];
Итерируемый < int > диапазон ( int start , int end ) => Список . генерировать ( конец - начало , ( я ) => начало + я );
Эликсир
для x <- 0 .. 100 , x * x > 3 , выполните : x * 2
Erlang
L = списки : seq ( 0 , 100 ). S = [ 2 * X || X <- L , X * X > 3 ].
F #
Последовательности с отложенным вычислением:
seq { for x in 0 .. 100 do if x * x > 3 then yield 2 * x }
Или для значений с плавающей запятой
seq { для x в 0 . .. 100 . делать, если х ** 2 . > 3 . затем вывести 2. * x }
Списки и массивы:
[ для x в 0 . .. 100 . делать, если х ** 2 . > 3 . тогда выведите 2. * x ] [| для x в 0 . .. 100 . делать, если х ** 2 . > 3 . затем вывести 2. * x |]
Понимание списков является частью более обширного семейства языковых конструкций, называемых вычислительными выражениями.
Groovy
( 0 .. 100 ). findAll { x -> x * x > 3 }. собрать { x -> 2 * x }
Haskell
[ 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 может создавать список так же просто, как и на других языках:
Диапазон от 0 до ( 100 ) asList select ( x , x * x > 3 ) map (* 2 )
ISLISP
Понимание списка можно выразить с помощью for
специальной формы. Условные выражения выражаются if
следующим образом:
( for (( x 0 ( + x 1 )) ( collect ())) (( > = x 100 ) ( обратный сбор )) ( if ( > ( * x x ) 3 ) ( setq collect ( cons ( * x 2 ) собираем ))))
Ява
Java с Streams API, [1] который включает интерфейс IntStream [2], который позволяет выполнять следующие операции:
Список < Целое число > ns = IntStream . диапазон ( 0 , 100 ) . фильтр ( x -> x * x > 3 ) . карта ( х -> х * 2 ) . в коробке (). собирать ( Коллекционеры . toList ());
JavaScript
[... диапазон ( 100 )]. фильтр ( x => x ** 2 > 3 ). карта ( x => 2 * x ) function * range ( start , stop , step = 1 ) { // диапазон (n) будет переназначен на диапазон (0, n, 1) if ( ! stop ) [ start , stop ] = [ 0 , start ] for ( let я = начало ; я < стоп ; я + = шаг ) { yield i ; } }
Юлия
Джулия поддерживает понимание, используя синтаксис:
у = [ х ^ 2 + 1 для х в 1 : 10 ]
и многомерные понимания, такие как:
z = [( x - 5 ) ^ 2 + ( y - 5 ) ^ 2 для x = 0 : 10 , y = 0 : 10 ]
Также можно добавить условие:
v = [ 3 x ^ 2 + 2 y ^ 2 для x в 1 : 7 для y в 1 : 7, если x % y == 0 ]
А просто заменив квадратные скобки на круглые, мы получим генератор:
g = ( 3 x ^ 2 + 2 y ^ 2 для x в 1 : 7 для y в 1 : 7, если x % y == 0 )
Мифрил
s = [2 * i для i в 1..100, где i * i> 3];
Несколько генераторов:
pyth = [(x, y, z) для x в 1..20 для y в x..20 для z в y..20, где x * x + y * y == z * z];
Nemerle
$ [ x * 2 | x в [ 0 .. 100 ], x * x > 3 ]
Ним
В модуле стандартной библиотеки сахара в Nim есть встроенные функции seq, set, table и object: [3]
импортный сахарlet variable = collect ( newSeq ): для элемента в @ [- 9 , 1 , 42 , 0 , - 1 , 9 ] : item + 1assert variable == @ [- 8 , 2 , 43 , 1 , 0 , 10 ]
Понимание реализовано как макрос, который раскрывается во время компиляции, вы можете увидеть расширенный код, используя параметр компилятора expandMacro :
var collectResult = newSeq ( Natural ( 0 )) для элемента в элементах ( @ [- 9 , 1 , 42 , 0 , - 1 , 9 ] ): add ( collectResult , item + 1 ) collectResult
Пояснения могут быть вложенными и многострочными:
импортный сахарlet values = collect ( newSeq ): для val в [ 1 , 2 ] : collect ( newSeq ): для val2 в [ 3 , 4 ] : if ( val , val2 ) ! = ( 1 , 2 ): ( val , val2 ) утверждать значения == @ [@ [ ( 1 , 3 ), ( 1 , 4 ) ] , @ [ ( 2 , 3 ), ( 2 , 4 ) ]]
OCaml
OCaml поддерживает понимание списков через OCaml Batteries . [4]
Perl
Массив со всеми числами от 1 до 9 включительно:
мои @doubles = map { $ _ * 2 } 1 .. 9 ;
Массив с именами клиентов из Рио-де-Жанейро (из массива хешей):
my @rjCustomers = map { $ _ -> { state } eq "RJ" ? $ _ -> { name } : ()} @customers ;
Фильтрация чисел, кратных 3:
мой @ divisibleBy3 = grep { $ _ % 3 == 0 } 0 .. 100 ;
Python
Python использует следующий синтаксис для выражения понимания списков над конечными списками:
S = [ 2 * x для x в диапазоне ( 100 ), если x ** 2 > 3 ]
Выражение генератора может быть использовано в версиях Python> = 2.4 , который дает ленивые вычисления над его входом, и может быть использован с генераторами для перебора «бесконечных» ввода , таких как функции генератора подсчета , который возвращает последовательные целые числа:
from itertools import count S = ( 2 * x for x in count (), если x ** 2 > 3 )
(Последующее использование выражения генератора определит, когда прекратить генерирование значений).
р
x <- 0 : 100 S <- 2 * x [ x ^ 2 > 3 ]
Ракетка
( для / list ([ x 100 ] #: when ( > ( * x x ) 3 )) ( * x 2 ))
Пример с несколькими генераторами:
( для * / list ([ x ( в диапазоне 1 21 )] [ y ( в диапазоне 1 21 )] [ z ( в диапазоне 1 21 )] #: when ( = ( + ( * x x ) ( * y y )) ( * z z ))) ( список x y z ))
Раку
my @s = ($ _ * 2, если $ _ ** 2> 3 для 0 .. 99);
Рубин
( 0 .. 100 ) . выберите { | х | х ** 2 > 3 } . карта { | х | 2 * x }
Ржавчина
В Rust нет встроенных списков, но многие из их возможностей можно воспроизвести с помощью итераторов:
let ns : Vec < _ > = ( 0 .. 100 ). фильтр ( | x | x * x > 3 ). карта ( | х | 2 * х ). собирать ();
Scala
Используя для понимания:
val s = for ( x <- от 0 до 100 ; если x * x > 3 ) дает 2 * x
Схема
Понимание списков поддерживается в Scheme за счет использования библиотеки SRFI -42. [5]
( list-ec ( : x 100 ) ( если ( > ( * x x ) 3 )) ( * x 2 ))
Пример понимания списка с использованием нескольких генераторов:
( list-ec ( : x 1 21 ) ( : y x 21 ) ( : z y 21 ) ( if ( = ( + ( * x x ) ( * y y )) ( * z z ))) ( список x y z ))
SETL
s: = {2 * x: x в {0..100} | х ** 2> 3};
Болтовня
(( От 1 до: 100 ) выберите: [ : x | x в квадрате > 3 ]) собрать: [ : x | х * 2 ]
Быстрый
// 0 2 4 6 ... 18 let timesTwo = ( 0 .. < 10 ). карта { $ 0 * 2 }
// Предположим, что isPrime: (Int) -> Bool - это функция, которая проверяет, является ли ее аргумент простым числом let primeBelow100 = ( 0. .. 100 ). фильтр ( isPrime )
Визуальный пролог
S = [ 2 * X || X = list :: getMember_nd ( L ) , X * X > 3 ]
PowerShell
$ s = ( 0 .. 100 | ? { $ _ * $ _ -gt 3 } | % { 2 * $ _ } )
что является сокращенным обозначением:
$ s = 0 .. 100 | где-объект { $ _ * $ _ -gt 3 } | foreach -object { 2 * $ _ }
Рекомендации
Внешние ссылки
- Сравнение понимания списков на rosettacode.org