我应该能够在 KDB 的嵌套字典中赋值吗?

Should I be able to assign in nested dictionaries in KDB?

根据文档,下面 `lt 的赋值应该有更新插入机制:

s:()!()
s[`MSFT]:(`state`sym)!(`init`MSFT)

    | state sym
----| ----------
MSFT| init  MSFT
s[`MSFT][`lt]: 3

'assign
  [0]  s[`MSFT][`lt]: 3
                    ^

但是我得到了一个错误。

我哪里做错了?

键控 table 是从 table 到 table 的映射,因此您索引到 s 的内容本身需要是 table。所以

(enlist `) ! enlist `MSFT

其次,如果您从空键 table 开始,则需要登记键和值。

q)s: () ! ()
q)s[enlist (enlist `) ! enlist `MSFT]: enlist (`state`sym) ! `init`MSFT
q)s
    | state sym 
----| ----------
MSFT| init  MSFT

当您的 table 不再为空时,您不需要登记键和值。

q)s[(enlist `) ! enlist `GOOG]: (`state`sym) ! `init`GOOG
q)s
    | state sym 
----| ----------
MSFT| init  MSFT
GOOG| init  GOOG

这又回到了之前使用类型化字典时遇到的相同问题(字典的值都是同一类型,因此 kdb 试图保持这种状态)- 这次它在两个深度发生了两次!

如果定义:

s:()!()
s[`MSFT]:(`state`sym)!(`init`MSFT)

然后 kdb 假定“值”的形状基于您第一次插入字典。在这种情况下,kdb 强制该字典中的任何值(甚至 MSFT 的值)都是具有键 state 和 sym 的字典。这意味着您不能通过添加第三个键来强制在其上创建新形状(至少不能以您尝试的方式)。

最重要的是 - 您创建的 sub-dictionary 本身是一个类型化的字典,其值都是符号,因此 kdb 将强制它保留符号值(也就是您不能突然使 "3 " 一个值)。

这里的最后一个问题是 Matthew 指出的 - 你不能使用双括号赋值 [][] 你只能用一个括号赋值(必要时使用深度)。

将所有这些放在一起:

/define s to allow generic datatype
q)s:(1#`)!enlist[::]
/also don't allow the inner dictionary to be typed
q)s[`MSFT]:(``state`sym)!(::;`init;`MSFT)
/now you can assign
q)s[`MSFT;`lt]:3
q)s
    | ::
MSFT| ``state`sym`lt!(::;`init;`MSFT;3)