लिस्ट कॉम्प्रिहेंशन

From Vigyanwiki

सूची समझ मौजूदा सूचियों के आधार पर सूची बनाने के लिए कुछ प्रोग्रामिंग भाषाओं में उपलब्ध एक वाक्यात्मक संरचना है। यह गणितीय सेट-बिल्डर संकेतन (सेट समझ) के रूप का अनुसरण करता है जो मानचित्र और फ़िल्टर फ़ंक्शंस के उपयोग से अलग है।

अवलोकन

सेट-बिल्डर संकेतन में निम्नलिखित उदाहरण पर विचार करें।

या प्रायः

इसे पढ़ा जा सकता है, " सभी संख्याओं का सेट है "2 गुना " SUCH THAT प्राकृतिक संख्याओं () के समुच्चय का ELEMENT या MEMBER है, AND का वर्ग से बड़ा है।"

सबसे छोटी प्राकृतिक संख्या, x = 1, स्थिति x2>3 को संतुष्ट करने में विफल रहती है (स्थिति 12>3 गलत है) इसलिए 2 ·1 को S में सम्मिलित नहीं किया गया है। अगली प्राकृतिक संख्या, 2, प्रत्येक अन्य प्राकृतिक संख्या की तरह शर्त (22>3) को संतुष्ट करती है। इस प्रकार x में 2, 3, 4, 5... होते हैं चूँकि सेट S में सभी संख्याएँ "2 गुना x" होती हैं, इसलिए इसे S = {4, 6, 8, 10,...} द्वारा दिया जाता है। दूसरे शब्दों में, S, 2 से बड़ी सभी सम संख्याओं का सेट है।

उदाहरण के इस एनोटेटेड संस्करण में-

  • एक इनपुट सेट के सदस्यों का प्रतिनिधित्व करने वाला चर है।
  • इनपुट सेट का प्रतिनिधित्व करता है, जो इस उदाहरण में प्राकृतिक संख्याओं का सेट है
  • इनपुट सेट के सदस्यों पर फ़िल्टर के रूप में कार्य करने वाली निर्धारक अभिव्यक्ति है।
  • आउटपुट अभिव्यक्ति है जो इनपुट सेट के सदस्यों से नए सेट के सदस्यों का उत्पादन करती है जो विधेय अभिव्यक्ति को संतुष्ट करते हैं।
  • ब्रेसिज़ इंगित करते हैं कि परिणाम एक सेट है
  • ऊर्ध्वाधर पट्टी को "SUCH THAT" के रूप में पढ़ा जाता है। बार और कोलन ":" का प्रयोग एक दूसरे के स्थान पर किया जाता है।
  • अल्पविराम निर्धारक को अलग करते हैं और इसे "AND" के रूप में पढ़ा जा सकता है।

सूची समझ में इनपुट सूची या पुनरावर्तक के क्रम में सूची की पीढ़ी का प्रतिनिधित्व करने के लिए समान वाक्यात्मक घटक होते हैं-

  • इनपुट सूची के सदस्यों का प्रतिनिधित्व करने वाला चर।
  • इनपुट सूची (या पुनरावर्तक)।
  • वैकल्पिक निर्धारक अभिव्यक्ति।
  • और आउटपुट अभिव्यक्ति, इनपुट पुनरावर्तनीय के सदस्यों से आउटपुट सूची के सदस्यों का उत्पादन करती है जो निर्धारक को संतुष्ट करते हैं।

आउटपुट सूची के सदस्यों की पीढ़ी का क्रम इनपुट में वस्तुओं के क्रम पर आधारित है।

हास्केल की सूची समझ सिंटैक्स में, यह सेट-बिल्डर निर्माण इसी तरह लिखा जाएगा, जैसे-

s = [ 2*x | x <- [0..], x^2 > 3 ]

यहां, सूची [0..] का प्रतिनिधित्व करती है, x^2>3 निर्धारक का प्रतिनिधित्व करती है, और 2*x आउटपुट अभिव्यक्ति का प्रतिनिधित्व करती है।

सूची समझ एक परिभाषित क्रम (सेट के सदस्यों के विपरीत) में परिणाम देती है और सूची की समझ किसी सूची के सदस्यों को क्रम में उत्पन्न कर सकती है, न कि संपूर्ण सूची तैयार करने से, उदाहरण के लिए, अनंत सूची के सदस्यों को पिछली हास्केल परिभाषा की अनुमति मिलती है।

इतिहास

संबंधित निर्माणों का अस्तित्व "सूची समझ" शब्द के उपयोग से पहले का है। एसईटीएल (SETL) प्रोग्रामिंग लैंग्वेज (1969) में एक सेट निर्माण संरचना है जो सूची समझ के समान है। उदाहरण के लिए, यह कोड 2 से N तक सभी अभाज्य संख्याओं को प्रिंट करता है-

प्रिंट([n in [2..N] | forall m in {2..n - 1} | n mod m > 0]);

कंप्यूटर बीजगणित प्रणाली एएक्सआईओएम (AXIOM) (1973) में समान निर्माण होता है जो स्ट्रीम को संसाधित करता है।

ऐसे निर्माणों के लिए "समझ" शब्द का प्रथम उपयोग रॉड बर्स्टल और जॉन डार्लिंगटन द्वारा 1977 से उनकी कार्यात्मक प्रोग्रामिंग भाषा एनपीएल (NPL) के विवरण में किया गया था। डेविड टर्नर अपने पूर्वव्यापी "कार्यात्मक प्रोग्रामिंग भाषाओं के कुछ इतिहास" में[1] याद करते हैं-

एनपीएल को बर्स्टॉल द्वारा पीओपी2 (POP2) में कार्यान्वित किया गया था और प्रोग्राम परिवर्तन (बर्स्टल और डार्लिंगटन 1977) पर डार्लिंगटन के काम के लिए उपयोग किया गया था। भाषा प्रथम क्रम की थी, दृढ़ता से (लेकिन बहुरूपी रूप से नहीं) टाइप की गई, पूरी तरह कार्यात्मक, कॉल-बाय-वैल्यू थी। इसमें "सेट अभिव्यक्तियाँ" भी थे जैसे

setofeven (X)  <=  <:x : x in X & even(x):>}}

"सूची समझ" शब्द से जुड़े फ़ुटनोट में, टर्नर यह भी नोट करता है

मैंने प्रारम्भ में इन जेडएफ (ZF) अभिव्यक्तियों को ज़र्मेलो-फ्रैंकल सेट सिद्धांत का संदर्भ कहा था - यह फिल वाडलर थे जिन्होंने बेहतर शब्द सूची समझ को गढ़ा था।

एनपीएल के साथ बर्स्टॉल और डार्लिंगटन के काम ने 1980 के दशक के दौरान कई कार्यात्मक प्रोग्रामिंग भाषाओं को प्रभावित किया, लेकिन सभी में सूची समझ सम्मिलित नहीं थी। 1985 में जारी टर्नर की प्रभावशाली, शुद्ध, मंद, कार्यात्मक प्रोग्रामिंग भाषा मिरांडा एक अपवाद थी। बाद में विकसित मानक शुद्ध मंद कार्यात्मक भाषा हास्केल में सूची समझ सहित मिरांडा की कई विशेषताएं सम्मिलित हैं।

समझ को डेटाबेस के लिए क्वेरी संकेतन के रूप में प्रस्तावित किया गया था[2] और इसे क्लेस्ली डेटाबेस क्वेरी भाषा में लागू किया गया था।[3]

विभिन्न प्रोग्रामिंग भाषाओं में उदाहरण

समान निर्माण

मोनाड समझ

हास्केल में, मोनैड समझ कार्यात्मक प्रोग्रामिंग में अन्य मोनैड के लिए सूची समझ का सामान्यीकरण है।

सेट समझ

पायथन भाषा का संस्करण 3.x और 2.7 सेट समझ के लिए सिंटैक्स का परिचय देता है। सूची समझ के समान, सेट समझ सूचियों के स्थान पर पायथन सेट उत्पन्न करते हैं।

>>> s = {v for v in 'ABCDABCD' if v not in 'CB'}
>>> print(s)
{'A', 'D'}
>>> type(s)
<class 'set'>
>>>

रैकेट सेट समझ सूचियों के स्थान पर रैकेट सेट उत्पन्न करती है।

(for/set ([v "ABCDABCD"] #:unless (member v (string->list "CB")))
         v))

शब्दकोश समझ

पायथन भाषा के संस्करण 3.x और 2.7 ने शब्दकोश समझ के लिए एक नया सिंटैक्स पेश किया, जो सूची समझ के रूप में समान था लेकिन जो सूचियों के स्थान पर पायथन डिक्ट उत्पन्न करता था।

>>> s = {key: val for key, val in enumerate('ABCD') if val not in 'CB'}
>>> s
{0: 'A', 3: 'D'}
>>>

रैकेट हैश टेबल समझ रैकेट हैश टेबल (रैकेट शब्दकोश प्रकार का कार्यान्वयन) उत्पन्न करती है।

(for/hash ([(val key) (in-indexed "ABCD")]
           #:unless (member val (string->list "CB")))
  (values key val))

समानांतर सूची समझ

ग्लासगो हास्केल संकलक में समानांतर सूची समझ (जिसे ज़िप-समझ के रूप में भी जाना जाता है) नामक एक्सटेंशन है जो सूची समझ सिंटैक्स के भीतर विशेषण की कई स्वतंत्र शाखाओं की अनुमति देता है। जबकि अल्पविराम द्वारा अलग किए गए विशेषण आश्रित ("नेस्टेड") होते हैं, पाइपों द्वारा अलग किए गए विशेषण शाखाओं का मूल्यांकन समानांतर (यह मल्टीथ्रेडेडनेस के किसी भी रूप को संदर्भित नहीं करता है- इसका अर्थ केवल यह है कि शाखाएं ज़िप की गई हैं) में किया जाता है।

-- regular list comprehension
a = [(x,y) | x <- [1..5], y <- [3..5]]
-- [(1,3),(1,4),(1,5),(2,3),(2,4) ...

-- zipped list comprehension
b = [(x,y) | (x,y) <- zip [1..5] [3..5]]
-- [(1,3),(2,4),(3,5)]

-- parallel list comprehension
c = [(x,y) | x <- [1..5] | y <- [3..5]]
-- [(1,3),(2,4),(3,5)]

रैकेट की समझ मानक लाइब्रेरी में इसकी समझ के समानांतर और नेस्टेड संस्करण सम्मिलित हैं, जो नाम में "फॉर" बनाम "फॉर*" द्वारा प्रतिष्ठित हैं। उदाहरण के लिए, वेक्टर समझ "फॉर/वेक्टर" और "फॉर*/वेक्टर" अनुक्रमों पर समानांतर बनाम नेस्टेड पुनरावृत्ति द्वारा वेक्टर बनाते हैं। हास्केल सूची समझ उदाहरणों के लिए रैकेट कोड निम्नलिखित है।

> (for*/list ([x (in-range 1 6)] [y (in-range 3 6)]) (list x y))
'((1 3) (1 4) (1 5) (2 3) (2 4) (2 5) (3 3) (3 4) (3 5) (4 3) (4 4) (4 5) (5 3) (5 4) (5 5))
> (for/list ([x (in-range 1 6)] [y (in-range 3 6)]) (list x y))
'((1 3) (2 4) (3 5))

पायथन में, हम निम्नानुसार कार्य कर सकते हैं-

# regular list comprehension
>>> a = [(x, y) for x in range(1, 6) for y in range(3, 6)]
[(1, 3), (1, 4), (1, 5), (2, 3), (2, 4), ...

# parallel/zipped list comprehension
>>> b = [x for x in zip(range(1, 6), range(3, 6))]
[(1, 3), (2, 4), (3, 5)]

जूलिया में, व्यावहारिक रूप से समान परिणाम निम्नानुसार प्राप्त किए जा सकते हैं-

# regular array comprehension
>>> a = [(x, y) for x in 1:5 for y in 3:5]

# parallel/zipped array comprehension
>>> b = [x for x in zip(1:3, 3:5)]

एकमात्र अंतर यह है कि जूलिया में सूचियों के स्थान पर, हमारे पास सारणियाँ हैं।

एक्सक्वेरी और एक्सपाथ

मूल एनपीएल उपयोग की तरह, ये मूलतः डेटाबेस एक्सेस भाषाएं हैं।

यह समझ की अवधारणा को और अधिक महत्वपूर्ण बनाता है, क्योंकि संपूर्ण सूची को पुनः प्राप्त करना और उस पर काम करना कम्प्यूटेशनल रूप से असंभव है (प्रारंभिक 'संपूर्ण सूची' संपूर्ण एक्सएमएल (XML) डेटाबेस हो सकती है)।

एक्सपाथ में, अभिव्यक्ति-

/library/book//paragraph[@style='first-in-chapter']

वैचारिक रूप से "चरणों" की श्रृंखला के रूप में मूल्यांकन किया जाता है जहां प्रत्येक चरण एक सूची तैयार करता है और अगला चरण पिछले चरण के आउटपुट में प्रत्येक तत्व पर फ़िल्टर फ़ंक्शन लागू करता है।[4]

एक्सक्वेरी में, पूर्ण एक्सपाथ उपलब्ध है, लेकिन एफएलडब्लयूओआर (FLWOR) कथनों का भी उपयोग किया जाता है, जो कि अधिक शक्तिशाली समझ निर्माण है।[5]

for $b in //book
where $b[@pages < 400]
order by $b//title
return
  <shortBook>
    <title>{$b//title}</title>
    <firstPara>{($book//paragraph)[1]}</firstPara>
  </shortBook>

यहां एक्सपाथ //पुस्तक का मूल्यांकन अनुक्रम (उर्फ सूची) बनाने के लिए किया जाता है जहां अनुच्छेद कार्यात्मक "फ़िल्टर" है, परिणाम को क्रमबद्ध करता है, और ‎<shortBook>...‎</shortBook> एक्सएमएल स्निपेट वास्तव में एक अज्ञात फ़ंक्शन है जो अन्य कार्यात्मक भाषाओं में पाए जाने वाले 'मैप' दृष्टिकोण का उपयोग करके अनुक्रम में प्रत्येक तत्व के लिए एक्सएमएल बनाता/बदलता है।

तो, किसी अन्य कार्यात्मक भाषा में उपरोक्त एफएलडब्लयूओआर कथन को इस प्रकार कार्यान्वित किया जा सकता है-

map(
  newXML(shortBook, newXML(title, $1.title), newXML(firstPara, $1...))
  filter(
    lt($1.pages, 400),
    xpath(//book)
  )
)

C# में एलआईएनक्यू (LINQ)

C# 3.0 में संबंधित सुविधाओं का एक समूह है जिसे एलआईएनक्यू कहा जाता है, जो ऑब्जेक्ट गणना में हेरफेर करने के लिए क्वेरी ऑपरेटरों के सेट को परिभाषित करता है।

var s = Enumerable.Range(0, 100).Where(x => x * x > 3).Select(x => x * 2);

यह एसक्यूएल (SQL) की याद दिलाते हुए वैकल्पिक समझ सिंटैक्स भी प्रदान करता है-

var s = from x in Enumerable.Range(0, 100) where x * x > 3 select x * 2;

एलआईएनक्यू विशिष्ट सूची समझ कार्यान्वयन पर क्षमता प्रदान करता है। जब समझ का मूल ऑब्जेक्ट आईक्वेरीबल(IQueryable) इंटरफ़ेस को कार्यान्वित करता है, तो केवल समझ की श्रृंखलाबद्ध विधियों को निष्पादित करने के स्थान पर, कमांड का पूरा अनुक्रम संक्षेप सिंटैक्स ट्री (एएसटी) ऑब्जेक्ट में परिवर्तित हो जाता है, जिसे व्याख्या और निष्पादित करने के लिए आईक्वेरीबल ऑब्जेक्ट को पास किया जाता है।

यह, अन्य बातों के अलावा, आईक्वेरीबल को इसकी अनुमति देता है

  • किसी असंगत या अप्रभावी समझ को दोबारा लिखें
  • निष्पादन के लिए एएसटी (AST) को किसी अन्य क्वेरी भाषा (उदाहरण के लिए एसक्यूएल) में अनुवाद करें

C++

C++ में सीधे तौर पर सूची समझ का समर्थन करने वाली कोई भाषा सुविधा नहीं है, लेकिन ऑपरेटर ओवरलोडिंग (उदाहरण के लिए, ओवरलोडिंग) है |, >>, >>=) एम्बेडेड क्वेरी डोमेन-विशिष्ट भाषाओं (डीएसएल) के लिए अभिव्यंजक वाक्यविन्यास प्रदान करने के लिए सफलतापूर्वक उपयोग किया गया है। वैकल्पिक रूप से, एक कंटेनर में तत्वों का चयन करने के लिए इरेज़-रिमूव मुहावरे का उपयोग करके सूची समझ का निर्माण किया जा सकता है और उन्हें बदलने के लिए STL एल्गोरिदम for_each का उपयोग किया जा सकता है।

#include <algorithm>
#include <list>
#include <numeric>

using namespace std;

template<class C, class P, class T>
C comprehend(C&& source, const P& predicate, const T& transformation)
{
  // initialize destination
  C d = forward<C>(source);

  // filter elements
  d.erase(remove_if(begin(d), end(d), predicate), end(d));

  // apply transformation
  for_each(begin(d), end(d), transformation);

  return d;
}

int main()
{
  list<int> range(10);
      // range is a list of 10 elements, all zero
  iota(begin(range), end(range), 1);
      // range now contains 1, 2, ..., 10

  list<int> result = comprehend(
      range,
      [](int x) { return x * x <= 3; },
      [](int &x) { x *= 2; });
      // result now contains 4, 6, ..., 20
}

C++ को सेट बिल्डर नोटेशन के समान सूची-समझ निर्माण/सिंटैक्स प्रदान करने में कुछ प्रयास किए गए हैं।

  • C++ लाइब्रेरीज़ को बूस्ट करें ़ में। रेंज [1] लाइब्रेरी में एडेप्टर की एक धारणा है [2] जिसे किसी भी रेंज पर लागू किया जा सकता है और फ़िल्टरिंग, ट्रांसफ़ॉर्मेशन आदि किया जा सकता है। इस लाइब्रेरी के साथ, मूल हास्केल उदाहरण जैसा दिखेगा (गुमनाम फ़िल्टरिंग और ट्रांसफ़ॉर्मिंग के लिए Boost.Lambda [3] का उपयोग करना) फ़ंक्शन) (पूर्ण उदाहरण):
    counting_range(1,10) | filtered( _1*_1 > 3 ) | transformed(ret<int>( _1*2 ))
    
  • यह[6] कार्यान्वयन एक मैक्रो का उपयोग करता है और << ऑपरेटर को ओवरलोड करता है। यह 'if' के अंदर मान्य किसी भी अभिव्यक्ति का मूल्यांकन करता है, और कोई भी चर नाम चुना जा सकता है। हालाँकि, यह थ्रेड सुरक्षा नहीं है। उपयोग उदाहरण:
list<int> N;
list<double> S;

for (int i = 0; i < 10; i++)
    N.push_back(i);

S << list_comprehension(3.1415 * x, x, N, x * x > 3)
  • यह[7] कार्यान्वयन कक्षाओं और ऑपरेटर ओवरलोडिंग का उपयोग करके हेड/टेल स्लाइसिंग प्रदान करता है, और | सूचियों को फ़िल्टर करने के लिए ऑपरेटर (फ़ंक्शन का उपयोग करके)। उपयोग उदाहरण:
bool even(int x) { return x % 2 == 0; }
bool x2(int &x) { x *= 2; return true; }

list<int> l, t;
int x, y;

for (int i = 0; i < 10; i++)
     l.push_back(i);

(x, t) = l | x2;
(t, y) = t;

t = l < 9;
t = t < 7 | even | x2;
  • एंबेडेड क्वेरी और ट्रैवर्सल के लिए भाषा (LEESA)।[8]) C++ में एक एम्बेडेड DSL है जो ऑपरेटर ओवरलोडिंग का उपयोग करके एक्स-पाथ-जैसी क्वेरीज़ को कार्यान्वित करता है। क्वेरीज़ को XSD से xml-to-c++ बाइंडिंग का उपयोग करके प्राप्त किए गए समृद्ध रूप से टाइप किए गए xml ट्री पर निष्पादित किया जाता है। बिल्कुल कोई स्ट्रिंग एन्कोडिंग नहीं है. यहां तक ​​कि एक्सएमएल टैग के नाम भी कक्षाएं हैं और इसलिए, टाइपो के लिए कोई रास्ता नहीं है। यदि LEESA एक्सप्रेशन गलत पथ बनाता है जो डेटा मॉडल में मौजूद नहीं है, तो C++ कंपाइलर कोड को अस्वीकार कर देगा।
    एक कैटलॉग xml पर विचार करें।
<catalog>
  <book>
    <title>Hamlet</title>
    <price>9.99</price>
    <author>
      <name>William Shakespeare</name>
      <country>England</country>
    </author>
  </book>
  <book>...</book>
...
</catalog>

लीसा प्रदान करता है >> XPath/विभाजक के लिए. XPath का // विभाजक जो पेड़ में मध्यवर्ती नोड्स को छोड़ देता है उसे LEESA में रणनीतिक प्रोग्रामिंग के रूप में जाना जाता है का उपयोग करके कार्यान्वित किया जाता है। नीचे दिए गए उदाहरण में, कैटलॉग_, पुस्तक_, लेखक_ और नाम_ क्रमशः कैटलॉग, पुस्तक, लेखक और नाम वर्गों के उदाहरण हैं।

// Equivalent X-Path: "catalog/book/author/name"
std::vector<name> author_names = 
evaluate(root, catalog_ >> book_ >> author_ >> name_);

// Equivalent X-Path: "catalog//name"
std::vector<name> author_names = 
evaluate(root, catalog_ >> DescendantsOf(catalog_, name_));

// Equivalent X-Path: "catalog//author[country=="England"]"
std::vector<name> author_names = 
evaluate(root, catalog_  >> DescendantsOf(catalog_, author_)
                         >> Select(author_, [](const author & a) { return a.country() == "England"; })
                         >> name_);


यह भी देखें

  • सेट-बिल्डर नोटेशन
  • SQL#क्वेरीज़ में इसके FROM और WHERE क्लॉज के साथ सेलेक्ट (SQL) स्टेटमेंट

नोट्स और संदर्भ

  1. Turner, David (2012). "कार्यात्मक प्रोग्रामिंग भाषाओं का कुछ इतिहास" (PDF). International Symposium on Trends in Functional Programming, Springer, Berlin, Heidelberg. pp. 1–20.
  2. Comprehensions, a query notation for DBPLs
  3. The functional guts of the Kleisli query system
  4. "2.1 Location Steps". XML Path Language (XPath). W3C. 16 November 1999. Archived from the original on 9 December 2012. Retrieved 24 December 2008.
  5. "XQuery FLWOR अभिव्यक्तियाँ". W3Schools. Archived from the original on 2011-10-08.
  6. "प्रीप्रोसेसर मैक्रोज़ का उपयोग करके C++ में एकल-चर सूची समझ". Archived from the original on 2011-08-21. Retrieved 2011-01-09.
  7. "सी++ सूची समझ". Archived from the original on 2017-07-07. Retrieved 2011-01-09.
  8. "Language for Embedded Query and Traversal (LEESA)".

बाहरी संबंध



स्वयंसिद्ध

क्लोजर

सामान्य लिस्प

हास्केल

OCaml

पायथन

श्रेणी:प्रोग्रामिंग निर्माण श्रेणी:उदाहरण कोड वाले लेख श्रेणी:हास्केल कोड के उदाहरण वाले लेख श्रेणी: पायथन (प्रोग्रामिंग भाषा) कोड के उदाहरण वाले लेख श्रेणी: उदाहरण रैकेट कोड वाले लेख