【问题标题】:Can I use the function "get" with an assoc list?我可以将函数“get”与关联列表一起使用吗?
【发布时间】:2013-12-21 13:22:07
【问题描述】:

我有以下代码:

(setq months '((january 1) (february 2) ...))

我可以使用get 将此列表用作地图(带有键和值)

喜欢:

(get 'months 'january)

并得到结果:1

是否可以在 Lisp 中执行此操作而无需像这样显式设置属性:

(setf (get 'months 'january) 1)
(setf (get 'months 'february) 2)
...

如果这在 Common Lisp 中是不可能的,那么在任何其他 Lisp 方言中是否可能?

【问题讨论】:

  • 为什么不使用ASSOC 来访问关联列表中的元素?为什么使用GET?那会有什么好处呢? GET 用于符号属性列表,而不用于关联列表。
  • @RainerJoswig 我是 LISP 的初学者。我不知道ASSOC。这是我一直在寻找的答案。谢谢!如果您将评论作为答案,我会将其标记为已接受的答案。
  • 初学者没什么错。首先询问 Emacs 非常有帮助,有两种方式:(1) 快速获得答案,(2) 了解 Emacs。它们是相关的,当 Emacs 回答您时,它会使用自己的术语,帮助您下次更好地询问它(或这里)。向 Emacs 询问有关 assoc 的信息:M-x apropos RET assoc RET。或尝试M-x apropos RET association list RET。 (尝试C-h c apropos TAB 以查看其他适当命令的列表。)

标签: lisp common-lisp


【解决方案1】:

没有。 documentation for get 表示用法是

获取交易品种指标 &optional default => value

get 在其属性的符号的属性列表中找到一个属性 指标与指标相同,并返回其对应的 适当的价值。如果该属性有多个属性1 指标,get 使用第一个这样的属性。如果没有财产 使用该属性指示符,返回默认值。

property list 定义为:

属性列表 n。 1. 包含偶数个元素的列表 是交替的名称(有时称为指标或键)和值 (有时称为属性)。当有多个名字并且 属性列表中具有相同名称的值对,第一个这样的 对确定属性。 2.(符号的)组成部分 包含属性列表的符号。

您的数据采用association list 的形式:

关联列表 n.代表一个关联的 conses 列表 带值的键,其中每个 cons 的 car 是键,cdr 是 与该键关联的值。

因此,您可以使用assoc 访问其中的值。您可以使用属性列表,在这种情况下,如果它不是符号的属性列表,您可以使用getf,如果它是符号的属性列表,则使用get(如上所述) .以下是所有三种方法的示例。

关联列表

CL-USER> (defparameter *months-alist*
           '((january . 1)
             (february . 2)
             (march . 3)))


*MONTHS-ALIST*
CL-USER> (cdr (assoc 'february *months-alist*))
2

属性列表

CL-USER> (defparameter *months-plist*
           '(january 1 february 2 march 3))
*MONTHS-PLIST*
CL-USER> (getf *months-plist* 'march)
3

符号的属性列表(不常见)

CL-USER> (setf (get '*months* 'january) 1
               (get '*months* 'february) 2
               (get '*months* 'march) 3)
3
CL-USER> (get '*months* 'january)
1

其他方式

当然,你也可以使用哈希映射,或者在这个数据排序的情况下,你可以找到一个元素的位置:

哈希表

CL-USER> (defparameter *months-hash* (make-hash-table :test 'eq))
*MONTHS-HASH*
CL-USER> (setf (gethash 'january *months-hash*) 1
               (gethash 'february *months-hash*) 2
               (gethash 'march *months-hash*) 3)
3
CL-USER> (gethash 'february *months-hash*)
2 ; the value
T ; it was present in the table

位置

CL-USER> (defparameter *months-sequence* 
           #(january february march april may june july august september))
*MONTHS-SEQUENCE*
CL-USER> (1+ (position 'april *months-sequence*))
4

【讨论】:

    【解决方案2】:

    您正在使用a-list 作为数据结构来实现关联映射。它具有 O(n) 复杂度(线性),因此对于大型地图来说不是一个好的结构。

    Common Lisp 有一个包含容器的丰富库,请参阅它的 hyperspec,尤其是 hash-tables。它们可能更相关。如果您认为 a-list 非常短,您仍然可以使用它们(例如,使用 ASSOC Common Lisp 函数)。你也可以考虑B-trees...

    【讨论】:

    • 我的问题是:有什么方法可以使用 GET,如 (GET 'months 'january),从列表中获得我想要的结果?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2012-01-12
    • 2021-03-14
    • 1970-01-01
    • 1970-01-01
    • 2015-05-12
    • 1970-01-01
    • 2020-08-19
    相关资源
    最近更新 更多