将一元函数映射到列表 - 为什么并不总是需要“每个”?

Mapping a unary function to a list - why is `each` not always required?

我正在阅读有关 q 的教程。 这是初始设置。

buys:2 1 4 3 5 4
sells:2 4 3 2

然后我定义了下面的函数

f:{x & (sums buys)}

我尝试在

中使用它
f (sums sells)

但是我得到以下错误

'length
  [1]  f:{x & (sums buys)}

我注意到,如果我这样做,它会起作用

q)f each (sums sells)
2 2 2 2  2  2
2 3 6 6  6  6
2 3 7 9  9  9
2 3 7 10 11 11

但是下面输出列表的一元函数应用没有问题

q){(x*x;x)} (1 2 3)
1 4 9
1 2 3

这两个函数的类型签名对我来说似乎是一样的。为什么一个得到评估而另一个引发错误?

您的 'length 错误是由于尝试对两个长度不同的列表执行 & 操作造成的。 我们可以检查调试会话中的变量,如果您在 REPL 上 运行 q 将让您进入。

q)f (sums sells)
'length
  [1]  f:{x & (sums buys)}
            ^
q))x
2 6 9 11
q))buys
2 1 4 3 5 4

& 要求两个列表的长度相同,或者一个输入是一个列表,一个是一个原子,所以它可以逐项比较。 考虑到这一点,我们可以看到

f each (sums sells)

之所以有效,是因为现在我们正在逐步浏览我们的 sums sells 列表,并一次将一个项目与我们的 buys 列表进行比较。

对于你的一元函数,这是有效的,因为 * 操作被应用于两个相同长度的整数列表,所以它总是有效的。

您可以在此处 https://code.kx.com/q4m3/6_Functions/

阅读更多关于函数(和底层向量思想)的信息

在这里对于凡人的q中有些详细:https://code.kx.com/q4m3/4_Operators/#45-greater-and-lesser

特别是“作为原子,它们在列表上逐项操作....”

一般来说,kdb/q想逐项进行列表操作,例如

q)1 2+2 3
3 5

如果你给它不同长度的列表:

q)1 2+1 2 3
'length
  [0]  1 2+1 2 3
          ^

不知道你要不要

q)1 2+\:1 2 3
2 3 4
3 4 5

q)1 2+/:1 2 3
2 3
3 4
4 5

同样适用于 & 你的情况。

您的其他函数不可比,因为它执行的唯一逐项操作 x*x 是在相同长度的列表上。所以没关系。

另一种破解方法只比较前四个(或任何数字)值 f:{x & (买入总和[直到卖出])}