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

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 से उनकी कार्यात्मक प्रोग्रामिंग भाषा एनपीएल प्रोग्रामिंग भाषा के विवरण में किया गया था। उनके पूर्वव्यापी कार्यात्मक प्रोग्रामिंग भाषाओं के कुछ इतिहास में,[1] डेविड_टर्नर_(कंप्यूटर_वैज्ञानिक) याद करते हैं:

NPL was implemented in POP2 by Burstall and used for Darlington’s work on program transformation (Burstall & Darlington 1977). The language was first order, strongly (but not polymorphically) typed, purely functional, call-by-value. It also had “set expressions” e.g.

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

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

I initially called these ZF expressions, a reference to Zermelo-Frankel set theory — it was Phil Wadler who coined the better term list comprehension.

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

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


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


समान रचनाएँ

मोनाड समझ

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

समझ सेट करें

पायथन भाषा का संस्करण 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 ने साहचर्य सरणी समझ के लिए एक नया वाक्यविन्यास पेश किया, जो सूची समझ के रूप में समान है, लेकिन इसके बजाय पायथन dicts उत्पन्न करता है। सूचियों का.

>>> 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 बनाम for* द्वारा प्रतिष्ठित हैं। उदाहरण के लिए, वेक्टर समझ for/vector और for*/vector अनुक्रमों पर समानांतर बनाम नेस्टेड पुनरावृत्ति द्वारा वैक्टर बनाते हैं। हास्केल सूची समझ उदाहरणों के लिए रैकेट कोड निम्नलिखित है।

> (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)]

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

XQuery और XPath

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

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

XPath में, अभिव्यक्ति:

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

वैचारिक रूप से चरणों की एक श्रृंखला के रूप में मूल्यांकन किया जाता है जहां प्रत्येक चरण एक सूची तैयार करता है और अगला चरण पिछले चरण के आउटपुट में प्रत्येक तत्व पर एक फ़िल्टर फ़ंक्शन लागू करता है।[4] XQuery में, पूर्ण XPath उपलब्ध है, लेकिन 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>

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

तो, किसी अन्य कार्यात्मक भाषा में उपरोक्त FLWOR कथन को इस तरह लागू किया जा सकता है:

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


C# में LINQ

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

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

यह एसक्यूएल की याद दिलाते हुए एक वैकल्पिक समझ वाक्यविन्यास भी प्रदान करता है:

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

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

यह, अन्य बातों के अलावा, IQueryable को अनुमति देता है

  • असंगत या अकुशल समझ को फिर से लिखें
  • निष्पादन के लिए एएसटी को किसी अन्य क्वेरी भाषा (जैसे एसक्यूएल) में अनुवाद करें

सी++

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

पायथन

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