关于Lisp中关联列表的基本问题

Chi*_*ron 13 lisp common-lisp land-of-lisp

我正在阅读"Lisp的土地"(顺便说一下,这是我读过的最好的技术书籍之一)我遇到了关联列表

  (defparameter *edges* 
     '((living-room (garden west door) 
                    (attic upstairs ladder))
      (garden (living-room east door)) 
      (attic (living-room downstairs ladder))))
Run Code Online (Sandbox Code Playgroud)

首先,Lisp中的关联列表与Java的Map(键值绑定)相同吗?
对于客厅钥匙,如何拥有多个价值?为什么不用列表包含值:

    (living-room ((garden west door) (attic upstairs ladder)))
Run Code Online (Sandbox Code Playgroud)

Nie*_*jou 13

  1. 是的,关联列表是表达键值关联的一种方式.Common Lisp为此提供的其他结构是属性列表和哈希表.

  2. 该值实际上已包含在列表中.alist基本上是对的列表,其中每对的汽车是钥匙,而cdr是与该钥匙相关联的值.如果您使用ASSOC查找关键LIVING-ROOM并将CDR应用于结果:

CL-USER> (cdr (assoc 'living-room *edges*))
((GARDEN WEST DOOR) (ATTIC UPSTAIRS LADDER))

这背后的魔力在于这样一个事实:由于列表是由成对构造的,因此一对汽车是living-room并且其cdr是两个元素的列表(garden west door)并且(attic upstairs ladder)也可以被视为三元素列表(living-room (garden west door) (attic upstairs ladder)).

通常,当将alists表示为带引号的对象时,您会看到用虚线对明确描述的元素,而不是使用列表表示法,例如:

(defparameter *edges* 
  '((living-room . ((garden west door)
                    (attic upstairs ladder)))
    (garden . ((living-room east door))) 
    (attic . ((living-room downstairs ladder))) ))

  • ASSOC为您提供*记录*.然后,您需要CAR或CDR来获取密钥/值. (2认同)

Rai*_*wig 5

ASSOC返回cons单元,因此包括键和值.

原因是这使得破坏性地更新值(或密钥)变得容易.

这里的更新隐藏在SETF后面:

CL-USER 11 > (defparameter *edges* 
               (copy-tree
                '((living-room (garden west door) 
                               (attic upstairs ladder))
                  (garden (living-room east door)) 
                  (attic (living-room downstairs ladder)))))
*EDGES*

CL-USER 12 > (assoc 'living-room *edges*)
(LIVING-ROOM (GARDEN WEST DOOR) (ATTIC UPSTAIRS LADDER))

CL-USER 13 > (cdr (assoc 'living-room *edges*))
((GARDEN WEST DOOR) (ATTIC UPSTAIRS LADDER))

CL-USER 14 > (setf (cdr (assoc 'living-room *edges*)) '((garden east door)))
((GARDEN EAST DOOR))

CL-USER 15 > (cdr (assoc 'living-room *edges*))
((GARDEN EAST DOOR))
Run Code Online (Sandbox Code Playgroud)