2012-12-07 63 views
3

好的風格使用cons來處理事物對還是堅持列表更好?lisp:good vs list

例如像問題和答案:

(list 
    (cons 
     "Favorite color?" 
     "red") 
    (cons 
     "Favorite number?" 
     "123") 
    (cons 
     "Favorite fruit?" 
     "avocado")) 

我的意思是,有些事情在對自然來;沒有必要可以容納兩個以上的東西,所以我覺得缺點是自然的選擇。不過,我也覺得我應該堅持一件事(名單)。

什麼是更好或更接受的風格?

+2

在適當的地方不使用缺點的唯一可能原因是爲了更容易地將代碼移植到缺乏完整細胞的低級Lisp方言(如Clojure)。 –

+1

查閱Google Common Lisp風格指南#Data Representation部分:https://google-styleguide.googlecode.com/svn/trunk/lispguide.xml#Data_Representation。希望這可以幫助! – juanitofatas

回答

9

你在那裏有一個association list(alist)。實際上,Alist條目通常是簡單的conses而不是列表(儘管這是一個偏好問題:有些人也使用alist條目列表),所以你擁有的是好的。雖然,我通常喜歡用文字語法:

'(("Favorite color?" . "red") 
    ("Favorite number?" . "123") 
    ("Favorite fruit?" . "avocado")) 

Alists通常使用符號作爲關鍵,因爲符號被拘留,所以符號alists可以使用assq代替assoc進行查找。以下是它的外觀:

'((color . "red") 
    (number . "123") 
    (fruit . "avocado")) 
+0

不在Common Lisp中。沒有'assq'函數,'assoc'默認爲'eql',但是使用關鍵字參數'key'來指定要使用的存取器而不是標識符,'test' /'test-not'指定一個等價函數。使用'eq'而不是默認的'eql'並不會真的買得多,而是以特定於實現的方式打破整數。 – Kaz

+0

@Kaz我是一個Schemer,所以顯然不能說CL(這個問題被標記爲兩個,所以我覺得要麼會這樣做)。問題是,'eql'比較字符串是否正確?當然,在Scheme中,'eqv?'不會按照人們期望的方式比較字符串。因此,建議使用符號(而不是字符串)作爲alist鍵仍然是正確的。 –

+0

不,'eql'不會比較字符串;它是'eq'樣式相等的擴展:對於大多數對象來說,它是「實現相等」,但是相同編號的不同實例是eql。 (eql 11) - > t,(eql 11.0) - > nil。你的建議對於Scheme來說是合理的。 – Kaz

3

這種情況下的默認數據結構應該是HASH-TABLE

cons cons的關聯列表也是一個可能的變體,並在歷史上被廣泛使用。這是一個有效的變體,因爲傳統和簡單。但是,如果對的數量超過了幾個(可能是10是一個很好的閾值),則不應該使用它,因爲搜索時間是線性的,而在散列表中它是不變的。

使用這個任務的列表也是可能的,但將是醜陋和低效率。

2

您需要根據情況自行決定。沒有普遍的答案。不同的任務與結構有不同的作用考慮以下幾點:

  • 在鍵盤的哈希表中搜索會更快,然後它在alist中。
  • 在處理alist時,使用迭代器並保存其狀態會更容易(散列表需要將其所有鍵作爲數組或列表導出並將指針導入該列表中,而這對於只記得指向alist的指針能夠恢復迭代器的狀態並繼續迭代
  • Alist vs list:因爲所有其他字符都是原子,所以它們對偶數個元素使用相同數量的conses當使用列表vs因此你必須確保沒有奇數元素(你可能會發現它太晚了),這很糟糕。
  • 但是還有更多的功能,包括內置的功能在正確的名單上工作,而不是在alist上工作。例如,nth將e如果它碰到cdr,這不是list,那麼它就是alist的錯誤。
  • 有些時候,某些宏不作爲你他們想與alists,例如,這樣的:正如你可能已經預期

(destructuring-bind (a b c d) 
    '((100 . 200) (300 . 400)) 
    (format t "~&~{~s~^,~}" (list a b c d))) 

將無法​​正常工作。

  • 另一方面,某些程序可能會被「欺騙」進行某些他們不適合正確列表的操作。例如,當複製複製列表中的alist時,只有cdrlist的conses將被重新複製(取決於情況,這可能是期望的結果)。