当深入索引字典时,我发现相同(如我所想的)结构中的不同结果:
q)d:`a`b!(1 2 3;4 5 6)
q)d[`a`b;0]
1 4
q)d[`a`b]0
1 2 3
为什么会这样?如何q
理解和区分两种不同的情况?在此之前我是有信心的,例如调用二元函数f[a;b]
和f[a]b
是一样的。现在我什至对此都不确定。
要深入索引,您要么需要用分号分隔参数,要么使用点。你的第二个例子,
d[`a`b] 0
从字典值中获取 2 个列表,然后索引以返回第一个。尽管
d[`a`b;0]
或者
d .(`a`b;0)
由于分号/点,正在获取 2 个列表,然后在深度索引,获取每个列表的第一个元素
当您调用二元函数时,它需要两个参数,在方括号内传递一个参数会创建一个投影,这基本上是使用隐式分号,所以
f[a]b
是相同的
f[a;]b
这与
f[a;b]
的结果
f[a]
是一个期待另一个参数的投影,所以
f[a] b
计算 f[a],然后将参数 b 传递给这个函数,通过并列使用通常的函数应用程序
您的字典索引示例不会创建投影,因此索引不需要更多参数,因此第一个索引
d[`a`b]
立即评估以给出结果,然后将第二个索引应用于此结果。对于一元函数,它的工作原理相同
q){5+til x}[5] 2
7
与顶级字典索引一样,执行应用程序,然后对结果进行索引,因为只需要一个参数,不涉及投影
编辑 - 亚当打败了我!
我认为您不能考虑函数调用f[a;b]
或f[a]b
等同于索引。f[a]b
因为函数是一个投影,但您不能以相同的方式投影索引。函数具有固定的化合价,也就是固定数量的输入,但可以在任何深度进行索引。
如果你把你的字典编造得更深入,你会发现你可以让索引越来越深:
q)d:{`a`b!2#enlist value x}/[1;d]
q)d[`a`b;1;1]
5 5
q)d:{`a`b!2#enlist value x}/[2;d]
q)d[`a`b;1;1;1;1]
5 5
q)d:{`a`b!2#enlist value x}/[2;d]
q)d[`a`b;1;1;1;1;1;1]
5 5
然而,您仍然可以仅在顶层建立索引d[`a`b]
。所以解释器必须决定它是在顶层d @ `a`b
索引还是在深度索引d . (`a`b;0)
。
为避免混淆,如果您提供一级索引,则它在顶级索引,如果您提供多于一级的索引,则在深度索引。因此没有预测(至少不是以相同的方式)。
如上所述,函数没有这种歧义,因为它们具有固定数量的参数,因此可以投影。
这里发生的是d[`a`b]
深度/价为d
. 因此,当您应用d[`a`b]0
零时,不会在深度索引。如果您不索引字典的多个值,您会得到预期的结果:
q)d[`a`b;0]~d[`a`b][0]
0b
q)d[`a;0]~d[`a][0]
1b
q)d[`b;0]~d[`b][0]
1b
如果您改为考虑与原始示例具有相同行为的 2x3 矩阵,这一点会更清楚
q)M:(1 2 3;4 5 6)
q)M[0 1;0]
1 4
q)M[0 1][0]
1 2 3
索引任何一行都会产生一个简单的向量
q)type M[0]
7h
q)type M[1]
7h
但是索引多于一行会产生一个矩阵:
q)type M[0 1]
0h
事实上,索引两行会产生相同的精确矩阵
q)M~M[0 1]
1b
所以我们应该期待
q)M[0]~M[0 1][0]
1b
正如我们在上面看到的。
这些都不会对调用二元函数产生影响,因为显式提供一个参数会导致函数投影,因此化合价总是会降低。
q)type {2+x*y}
100h
q)type {2+x*y}[10]
104h