Спискові вирази (англ. list comprehension) — синтаксична конструкція в деяких мовах програмування, для створення списків застосуванням операцій над уже наявними списками. Вона відповідає математичній нотації побудови множини і замінює використання функцій map та filter.
Опис
Розгляньмо наступний приклад запису множини:
Це можна прочитати як, « множина всіх чисел виду „2 на “, де — елемент з множини натуральних чисел (), такий що у квадраті більше, ніж .»
В мові Haskell такий запис множини можна відтворити таким списковим виразом:
s = [ 2*x | x <- [1..], x^2 > 3 ]
Тут список [1..]
представляє , x^2>3
представляє предикат, а 2*x
— вихідний вираз.
Спискові вирази дають результати в означеному порядку (на відміну від членів множини) і можуть ґенерувати елементи за потребою, а не одразу весь список, дозволяючи таким чином, наприклад, попереднє означення членів нескінченної множини.
Історія
Мова програмування SETL (кінець 1960-тих) мала інструкції конструювання множин, і система комп'ютерної алґебри AXIOM (1973) мала подібні конструкції, які обробляли потоки, але вперше термін «comprehension» для таких конструкцій був використаний Родом Бурсталом та Джоном Дарлінґтоном в описі мови програмування NPL (1977).
Smalltalk block context messages, якими є спискові вирази, були в цій мові щонайменше з часів Smalltalk-80.
Робота Бурстала та Дарглінґтона з NPL вплинула на багато мов програмування протягом 1980-тих, але не всі з них включали спискові вирази. Винятком була впливова лінива чисто функціональна мова програмування , випущена в 1985-тому. Розроблена пізніше, теж цілком функціональна мова з лінивими обчисленнями Haskell, увібрала багато особливостей Міранди, включно з списковими виразами. Мова програмування Python теж зазнала сильного впливу лінивих функціональних мов і ввела спискові вирази. Чисті функціональні мови залишаються нішевими, у той час як Python став значно популярнішим і представив спискові вирази ширшій авдиторії.
Спискові вирази пропонувались як нотація запитів до баз даних і були реалізовані в мові запитів Kleisli.
Приклади в різних мовах програмування
Далі йтимуть приклади синтаксису спискових виразів у різних мовах програмування: Хоча в оригінальному прикладі використовується нескінченний список, виразити його можуть не всі мови, тому в деяких ми покажемо як використати підмножину замість підмножини .
var s = from x in Enumerable.Range(0, 100) where x * x > 3 select x * 2;
чи
var s = Enumerable.Range(0, 100).Where(x => x*x > 3).Select(x => x*2);
{ for (x in 0..100) if ( x**2 > 3) x * 2 }
Clojure ґенерує нескінченні ліниві послідовності (подібно до Гаскеля, чи ґенераторів Пайтона). Використовуйте take
щоб отримати перші N результатів нескінченної послідовности.
(take 20 (for [x (iterate inc 0) :when (> (* x x) 3)] (* 2 x)))
(x * 2 for x in [0..20] when x*x > 3)
Спискові вирази можуть виражатись за допомогою ключового слова collect
макроса loop
. Умови виражаються за допомогою if
, як показано нижче:
(loop for x from 0 to 100 if (> (* x x) 3) collect (* 2 x))
Нескінченна лінива послідовність може створюватись різними способами, наприклад за допомогою об'єктів CLOS чи макросом yield.
S = [2*X || X <- lists:seq(0,100), X*X > 3].
Вирази мають форму [for x in collection do ... yield expr]
для списків та seq {for x in collection do ... yield expr}
для послідовностей.
> seq { for x in 0..100 do if x*x > 3 then yield 2*x } ;; val it : seq<int> = seq [4; 6; 8; 10; ...]
Groovy підтримує вирази для таких колекцій в Java як list, set, map.
s = (1..100).grep { it ** 2 > 3 }.collect { it * 2 }
Змінна «it» є скороченням неявного параметра замикання. Наступний код є еквівалентом попереднього
s = (1..100).grep { x -> x ** 2 > 3 }.collect { x -> x * 2 }
s = [ 2*x | x <- [0..], x^2 > 3 ]
my @s = ($_ * 2 if $_ ** 2 > 3 for ^100);
чи:
my @s = gather { for ^100 { take 2 * $_ if $_ ** 2 > 3 } };
0..100 | Where {$_ * $_ -gt 3} | ForEach {$_ * 2}
S = [2*x for x in range(101) if x**2 > 3]
Див. також
Посилання
- Comprehensions, a query notation for DBPLs
- The functional guts of the Kleisli query system
- in The Free On-line Dictionary of Computing, Editor Denis Howe.
- Trinder, Phil (1992). Comprehensions, a query notation for DBPLs. Proceedings of the third international workshop on Database programming languages: bulk types & persistent data, Nafplion, Greece. с. 55—68.
- Wadler, Philip (1990). . Proceedings of the 1990 ACM Conference on LISP and Functional Programming, Nice. Архів оригіналу за 29 березня 2008. Процитовано 22 липня 2011.
- Wong, Limsoon (2000). The Functional Guts of the Kleisli Query System. Proceedings of the fifth ACM SIGPLAN international conference on Functional programming. International Conference on Functional Programming. с. 1—10.
Haskell
- The Haskell 98 Report, chapter 3.11 List Comprehensions [ 11 листопада 2020 у Wayback Machine.].
- The Glorious Glasgow Haskell Compilation System User's Guide, chapter .
- The Hugs 98 User's Guide, chapter .
OCaml
- OCaml Batteries Included [ 26 червня 2011 у Wayback Machine.]
- Language extensions introduced in OCaml Batteries Included [ 3 березня 2016 у Wayback Machine.]
Python
- Python Reference Manual, chapter .
- Python Enhancement Proposal PEP 202: List Comprehensions [ 16 травня 2008 у Wayback Machine.].
- Python Reference Manual, chapter .
- Python Enhancement Proposal PEP 289: Generator Expressions [ 6 вересня 2008 у Wayback Machine.].
Common Lisp
- Implementation of a Lisp comprehension macro [ 19 липня 2011 у Wayback Machine.] by Guy Lapalme
Clojure
- Clojure API documentation — for macro [ 22 липня 2011 у Wayback Machine.]
Axiom
Решта
- SQL-подібні оператори над множинами в Python Cookbook [ 2 липня 2008 у Wayback Machine.] (англ.)
- Обговорення генераторних списків та пов'язаних конструкцій в Scheme [ 28 липня 2020 у Wayback Machine.] (англ.)
- Генераторні списки в різних мовах програмування [ 9 листопада 2020 у Wayback Machine.] (англ.)
Вікіпедія, Українська, Україна, книга, книги, бібліотека, стаття, читати, завантажити, безкоштовно, безкоштовно завантажити, mp3, відео, mp4, 3gp, jpg, jpeg, gif, png, малюнок, музика, пісня, фільм, книга, гра, ігри, мобільний, телефон, android, ios, apple, мобільний телефон, samsung, iphone, xiomi, xiaomi, redmi, honor, oppo, nokia, sonya, mi, ПК, web, Інтернет
Spiskovi virazi angl list comprehension sintaksichna konstrukciya v deyakih movah programuvannya dlya stvorennya spiskiv zastosuvannyam operacij nad uzhe nayavnimi spiskami Vona vidpovidaye matematichnij notaciyi pobudovi mnozhini i zaminyuye vikoristannya funkcij map ta filter OpisRozglyanmo nastupnij priklad zapisu mnozhini S 2 x x N x2 gt 3 displaystyle S 2 cdot x mid x in mathbb N x 2 gt 3 Ce mozhna prochitati yak S displaystyle S mnozhina vsih chisel vidu 2 na x displaystyle x de x displaystyle x element z mnozhini naturalnih chisel N displaystyle mathbb N takij sho x displaystyle x u kvadrati bilshe nizh 3 displaystyle 3 V movi Haskell takij zapis mnozhini mozhna vidtvoriti takim spiskovim virazom s 2 x x lt 1 x 2 gt 3 Tut spisok 1 predstavlyaye N displaystyle mathbb N x 2 gt 3 predstavlyaye predikat a 2 x vihidnij viraz Spiskovi virazi dayut rezultati v oznachenomu poryadku na vidminu vid chleniv mnozhini i mozhut generuvati elementi za potreboyu a ne odrazu ves spisok dozvolyayuchi takim chinom napriklad poperednye oznachennya chleniv neskinchennoyi mnozhini IstoriyaMova programuvannya SETL kinec 1960 tih mala instrukciyi konstruyuvannya mnozhin i sistema komp yuternoyi algebri AXIOM 1973 mala podibni konstrukciyi yaki obroblyali potoki ale vpershe termin comprehension dlya takih konstrukcij buv vikoristanij Rodom Burstalom ta Dzhonom Darlingtonom v opisi movi programuvannya NPL 1977 Smalltalk block context messages yakimi ye spiskovi virazi buli v cij movi shonajmenshe z chasiv Smalltalk 80 Robota Burstala ta Darglingtona z NPL vplinula na bagato mov programuvannya protyagom 1980 tih ale ne vsi z nih vklyuchali spiskovi virazi Vinyatkom bula vplivova liniva chisto funkcionalna mova programuvannya vipushena v 1985 tomu Rozroblena piznishe tezh cilkom funkcionalna mova z linivimi obchislennyami Haskell uvibrala bagato osoblivostej Mirandi vklyuchno z spiskovimi virazami Mova programuvannya Python tezh zaznala silnogo vplivu linivih funkcionalnih mov i vvela spiskovi virazi Chisti funkcionalni movi zalishayutsya nishevimi u toj chas yak Python stav znachno populyarnishim i predstaviv spiskovi virazi shirshij avditoriyi Spiskovi virazi proponuvalis yak notaciya zapitiv do baz danih i buli realizovani v movi zapitiv Kleisli Prikladi v riznih movah programuvannyaDali jtimut prikladi sintaksisu spiskovih viraziv u riznih movah programuvannya Hocha v originalnomu prikladi vikoristovuyetsya neskinchennij spisok viraziti jogo mozhut ne vsi movi tomu v deyakih mi pokazhemo yak vikoristati pidmnozhinu 0 1 100 displaystyle 0 1 100 zamist pidmnozhini N displaystyle mathbb N C var s from x in Enumerable Range 0 100 where x x gt 3 select x 2 chi var s Enumerable Range 0 100 Where x gt x x gt 3 Select x gt x 2 Ceylon for x in 0 100 if x 2 gt 3 x 2 Clojure Clojure generuye neskinchenni linivi poslidovnosti podibno do Gaskelya chi generatoriv Pajtona Vikoristovujte take shob otrimati pershi N rezultativ neskinchennoyi poslidovnosti take 20 for x iterate inc 0 when gt x x 3 2 x CoffeeScript x 2 for x in 0 20 when x x gt 3 Common Lisp Spiskovi virazi mozhut virazhatis za dopomogoyu klyuchovogo slova collect makrosa loop Umovi virazhayutsya za dopomogoyu if yak pokazano nizhche loop for x from 0 to 100 if gt x x 3 collect 2 x Neskinchenna liniva poslidovnist mozhe stvoryuvatis riznimi sposobami napriklad za dopomogoyu ob yektiv CLOS chi makrosom yield Erlang S 2 X X lt lists seq 0 100 X X gt 3 F Virazi mayut formu for x in collection do yield expr dlya spiskiv ta seq for x in collection do yield expr dlya poslidovnostej gt seq for x in 0 100 do if x x gt 3 then yield 2 x val it seq lt int gt seq 4 6 8 10 Groovy Groovy pidtrimuye virazi dlya takih kolekcij v Java yak list set map s 1 100 grep it 2 gt 3 collect it 2 Zminna it ye skorochennyam neyavnogo parametra zamikannya Nastupnij kod ye ekvivalentom poperednogo s 1 100 grep x gt x 2 gt 3 collect x gt x 2 Haskell s 2 x x lt 0 x 2 gt 3 Raku my s 2 if 2 gt 3 for 100 chi my s gather for 100 take 2 if 2 gt 3 PowerShell 0 100 Where gt 3 ForEach 2 Python S 2 x for x in range 101 if x 2 gt 3 Div takozhOperator SELECT v SQL Monadi Inshi konstrukciyi dlya obrobki poslidovnostej Generator programuvannya map funkciya vishogo poryadku filter funkciya vishogo poryadku Inshi konstrukciyi programuvannya pereneseni z matematichnih form zapisu Varta Zistavlennya iz vzircem Operator programuvannya PosilannyaComprehensions a query notation for DBPLs The functional guts of the Kleisli query system in The Free On line Dictionary of Computing Editor Denis Howe Trinder Phil 1992 Comprehensions a query notation for DBPLs Proceedings of the third international workshop on Database programming languages bulk types amp persistent data Nafplion Greece s 55 68 Wadler Philip 1990 Proceedings of the 1990 ACM Conference on LISP and Functional Programming Nice Arhiv originalu za 29 bereznya 2008 Procitovano 22 lipnya 2011 Wong Limsoon 2000 The Functional Guts of the Kleisli Query System Proceedings of the fifth ACM SIGPLAN international conference on Functional programming International Conference on Functional Programming s 1 10 Haskell The Haskell 98 Report chapter 3 11 List Comprehensions 11 listopada 2020 u Wayback Machine The Glorious Glasgow Haskell Compilation System User s Guide chapter The Hugs 98 User s Guide chapter OCaml OCaml Batteries Included 26 chervnya 2011 u Wayback Machine Language extensions introduced in OCaml Batteries Included 3 bereznya 2016 u Wayback Machine Python Python Reference Manual chapter Python Enhancement Proposal PEP 202 List Comprehensions 16 travnya 2008 u Wayback Machine Python Reference Manual chapter Python Enhancement Proposal PEP 289 Generator Expressions 6 veresnya 2008 u Wayback Machine Common Lisp Implementation of a Lisp comprehension macro 19 lipnya 2011 u Wayback Machine by Guy LapalmeClojure Clojure API documentation for macro 22 lipnya 2011 u Wayback Machine Axiom Reshta SQL podibni operatori nad mnozhinami v Python Cookbook 2 lipnya 2008 u Wayback Machine angl Obgovorennya generatornih spiskiv ta pov yazanih konstrukcij v Scheme 28 lipnya 2020 u Wayback Machine angl Generatorni spiski v riznih movah programuvannya 9 listopada 2020 u Wayback Machine angl