在lisp中的好风格:缺点与列表

时间:2012-12-07 02:34:00

标签: lisp scheme common-lisp

对于成对的东西使用cons是好的风格还是最好坚持列表?

比如问题和答案:

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

我的意思是,有些东西自然成对出现;没有必要能够容纳超过两个的东西,所以我觉得缺点是自然的选择。但是,我也觉得我应该坚持一件事(列表)。

什么是更好或更容易接受的风格?

3 个答案:

答案 0 :(得分:9)

你所拥有的是association list(alist)。 Alist条目实际上通常是简单的conses而不是列表(虽然这是一个偏好的问题:有些人也使用列表作为alist条目),所以你拥有的很好。虽然,我通常更喜欢使用文字语法:

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

Alists通常使用符号作为键,因为符号是实际的,因此可以使用assq而不是assoc查找符号列表。这是它的外观:

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

答案 1 :(得分:3)

此类案例的默认数据结构应为HASH-TABLE

cons对的关联列表也是一种可能的变体,并且在历史上被广泛使用。由于传统和简单,它是一种有效的变体。但你不应该使用它,当对的数量超过几个(可能,10是一个好的阈值),因为搜索时间是线性的,而在哈希表中它是恒定的。

使用此任务的列表也是可能的,但是既丑又低效。

答案 2 :(得分:2)

您需要根据具体情况自行决定。没有一个普遍的答案。不同的任务与结构不同。请考虑以下事项:

  • 在哈希表中搜索密钥更快,然后它就在alist中。
  • 使用alist时更容易拥有迭代器并保存其状态(hash-table需要将其所有键导出为数组或列表,并且指针指向该列表,但它足以只记得指向alist的指针才能恢复迭代器的状态并继续迭代。
  • Alist vs list:对于偶数个元素,它们使用相同数量的conses,因为所有其他字符都是原子。当使用列表与列表时,你必须确保没有奇数个元素(你可能发现它太晚了),这很糟糕。
  • 但是还有很多功能,包括内置的功能,它们适用于正确的列表,而不适用于alists。例如,如果nth点击cdr而非list,则(destructuring-bind (a b c d) '((100 . 200) (300 . 400)) (format t "~&~{~s~^,~}" (list a b c d))) 会出错。
  • 有时某些宏不会像你想要的那样起作用,例如:

cdr

不会像您预期的那样有效。

  • 另一方面,某些程序可能会被“欺骗”到他们没有为正确的列表做的事情上。例如,在复制带有副本列表的alist时,只会复制list为{{1}}的conses(根据具体情况而定,这可能是期望的结果)。