क्या वास्तव में एक सूची है?


15

मैं वास्तव में .संकेतन के साथ भ्रमित हूँ । है '(a . b)एक सूची?

(listp '(a . b))रिटर्न tलेकिन जब मैं जानना चाहता हूं कि इसकी लंबाई (length '(a . b))एक त्रुटि है Wrong type argument: listp, b। अन्य कार्यों के लिए भी यही है, nth,mapcarवे सभी एक ही त्रुटि देते हैं

क्या कोई कार्य है जो मैं '(a b)और के बीच अंतर कर सकता हूं '(a . b)?


प्रसंग: जब मैं पुनरावर्ती संस्करण लागू करना चाहता था तो मुझे इस समस्या का सामना करना पड़ा mapcar। यहाँ मेरा कार्यान्वयन है

(defun true-listp (object)
"Return non-`nil' if OBJECT is a true list."
(and (listp object)  (null (cdr (last object)))))

(defun recursive-mapcar (func list)
"Evaluates func on elements of the list, then on elements of elements  of the list and so forth." 
(let ((output nil))
(flet ((comp (a b) nil)
       (call-fun-and-save (x) (add-to-list 'output (funcall func x) t 'comp))
       (recursion (l)
                  (mapcar
                   (lambda (x)
                     (call-fun-and-save x)
                     (if (and (true-listp x))  ;; HERE I use true-listp, testing for list or cons is not sufficient
                         (recursion x)))
                    l)))
   (recursion list))
  output))

मैं पार्स किए गए html से सभी विशिष्ट टैग निकालने के लिए इसका उपयोग करता हूं। htmlपार्स का उदाहरण

;; buffer 'html'
<html>
<body>
<table style="width:100%">
  <tr>  <td>Jill</td>  <td>Smith</td>  <td>50</td> </tr>
  <tr>  <td>Eve</td>   <td>Jackson</td>   <td>94</td> </tr>
</table>
</body>
</html>

फिर मैं सभी <td>को निकालता हूं

(with-current-buffer (get-buffer "html")
  (let ((data (libxml-parse-html-region (point-max) (point-min))))

    ;; gat only <td> tags
    (-non-nil
     (recursive-mapcar
      (lambda(x) (and (consp x) (equal 'td (car x)) x))
      data))
    data
    )
  )

1
true-list-pएलीस्प में कोई बस नहीं है क्योंकि इसे उपलब्ध कराने के लिए पर्याप्त उपयोगी नहीं पाया गया है। वास्तव में, मुझे याद नहीं है कि पिछली बार मैं परीक्षण करना चाहता था कि क्या कोई सूची उचित थी, इसलिए यदि आप हमें अपने उपयोग-मामले के बारे में कुछ और जानकारी देते हैं तो हम आपकी समस्या को दूसरे तरीके से हल करने में मदद कर सकते हैं।
स्टीफन

@Stefan संक्षेप में, मैं पुनरावर्ती मानचित्रकार को लागू करना चाहता हूं, मैं किसी दिए गए सूची के तत्वों पर दिए गए फ़ंक्शन का मूल्यांकन करता हूं, फिर सूची के तत्वों के तत्वों पर, फिर सूची के तत्वों के तत्वों पर और इसके बाद। इसलिए मुझे यह जानने की जरूरत है कि कोई तत्व सही सूची है या नहीं।
टॉम

यह उदाहरण के लिए उपयोगी है जब मैं html को पार्स करता libxml-parse-html-regionहूं और मैं सभी <td>टैग निकालना चाहता हूं ।
टॉम

क्या आप हमें एक ठोस उदाहरण दिखा सकते हैं, जहाँ आपको एक उचित सूची, या एक अनुचित सूची, या कुछ और मिल सकती है, और जहाँ आपको अलग-अलग ३ मामलों को संभालने की आवश्यकता है? ज्यादातर मामलों में, मुझे "उचित" और "अनुचित" मामलों से निपटना पड़ता है, जब तक कि हम वास्तविक अनुचित पूंछ से नहीं मिलते हैं, तब तक आप साझा कर सकते हैं, इसलिए आपको फिर से परीक्षण करने की आवश्यकता नहीं है कि क्या यह उचित है या नहीं: बस परीक्षण करें यदि इसके conspबजाय है।
स्टेफन

1
libxml सिर्फ सूचियों की सूची वापस नहीं करता है। XML तत्व का प्रतिनिधित्व करने वाली प्रत्येक सूची में प्रपत्र (प्रतीक विशेषताएँ। सामग्री) है। इसलिए आपका कोड सूची के सभी तत्वों पर केवल मानचित्रकार को लागू नहीं करना चाहिए, केवल cddrसूची के आधार पर (तत्व नाम और विशेषताओं को छोड़ने के लिए)। एक बार जब आप ऐसा कर लेते हैं, तो आपको यह पता लगाना चाहिए कि सभी सूचियाँ उचित हैं और आपकी समस्या गायब हो जाएगी। यह आपके कोड में एक बग को भी ठीक करेगा जहां आप tdएक tdतत्व के लिए एक विशेषता को भ्रमित कर सकते हैं ।
स्टीफन

जवाबों:


22

यह संतोषजनक है listp, इसलिए इस अर्थ में यह एक सूची है। listpबस परीक्षण करता है कि क्या कुछ एक तरफ या nil(उर्फ ()) है, या दूसरी तरफ कुछ और है।

एक उचित सूची या सच्ची सूची (या एक सूची जो एक बिंदीदार सूची या एक गोलाकार सूची नहीं है) कुछ ऐसा है जो इसकी अंतिम सीडीआर के रूप में listpभी है nil। यही कारण है, एक सूची XSहै उचित अगर (cdr (last XS))है nil(और है कि आप इसे कैसे भेद है)।

इसे लगाने का एक और तरीका यह है कि एक उचित सूची की अपनी सीडीआर के रूप में एक उचित सूची है । यह डेटा प्रकार (उचित) सूची टाइप भाषाओं में परिभाषित किया गया है। यह एक सामान्य और पुनरावर्ती प्रकार की परिभाषा है: जेनेरिक भाग कहता है कि गैर-रिक्त सूची निर्माणकर्ता (जिसे अक्सर consBTW कहा जाता है ) के लिए पहला तर्क किसी भी प्रकार का हो सकता है। पुनरावर्ती भाग कहता है कि इसका दूसरा तर्क प्रकार (उचित) सूची का एक उदाहरण है ।

हां, आप जांचते हैं कि क्या किसी listpका उपयोग करके उचित सूची (cdr (last XS))है nil। यह जांचने के लिए कि क्या क्रेटर की सीडीआर स्वयं एक उचित सूची है, आपको इसकी सीडीआर की जांच जारी रखनी चाहिए, अंतिम अंत तक - अंतिम विपक्ष, यह देखने के लिए कि क्या यह है nil। यदि आप चाहते हैं, तो आप इसके लिए एक विधेय को इस प्रकार परिभाषित कर सकते हैं:

(defun true-listp (object)
  "Return non-`nil' if OBJECT is a true list."
  (and (listp object)  (null (cdr (last object)))))

हालांकि एक परिपत्र सूची का कोई अंत नहीं है, Emacs (Emacs 24 के साथ शुरू) lastसही ढंग से जांचने के लिए पर्याप्त स्मार्ट है , इसलिए यह कोड एक गोलाकार सूची के लिए भी काम करता है (लेकिन केवल Emacs 24.1 और बाद के संस्करणों के लिए; पहले के संस्करणों के लिए आपको एक "अनंत" पुनरावर्तन मिलता है; जब तक ढेर अतिप्रवाह)।

आप lengthकेवल उचित सूचियों और अन्य अनुक्रमों जैसे कार्यों का उपयोग कर सकते हैं । समारोह भी देखें safe-length

एलिस मैनुअल, नोड कॉन्स सेल देखें

अंकन के लिए के रूप में, (a b)बस के लिए वाक्यविन्यास चीनी है (a . (b . nil))- Elisp मैनुअल, नोड डॉटेड जोड़ी संकेतन देखें


उचित सूची के लिए जाँच करने के लिए सबसे अच्छा अभ्यास क्या है? अगर crumblesome (cdr (last XS))है जाँच कर रहा है nil। वहाँ एक समारोह की तरह नहीं है proper-list-p?
टॉम

@tom: कि, या कुछ समतुल्य, आवश्यक है - आपको अंतिम कॉन्स सेल की जाँच करनी चाहिए। मैंने उत्तर में इसके बारे में अधिक जोड़ा है।
ड्रयू

@ मुझे फंक्शन की बॉडी बदलनी चाहिए (unless (atom x) (not (cdr (last x))))ताकि आप कॉल कर सकें (true-list-p "text")और nilकोई त्रुटि न हो ।
टॉम

@ टोम: राइट; धन्यवाद। वास्तव में, यह सुनिश्चित करने के लिए पहले परीक्षण किया जाना चाहिए कि यह एक आम सहमति है nil(यानी, listp)। (इसके अलावा, Fwiw, मैं उपयोग नहीं करते unlessया whenउनकी वापसी मूल्य के लिए मैं का उपयोग करें। and, orऔर ifउस के लिए।)
ड्रयू
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.