如何在KDB/Q中断言列或列表是否有序?
Q语言实现有序性判断(带短路线性探测)
需求背景
给定Q语言里的两个列表:
a: 1 2 3 4; b: 1 2 3 2;
我们需要判断a是升序有序的,b是无序的,同时要实现类似下面Python代码的带短路线性探测算法——也就是一旦找到逆序元素就立刻返回结果,不用遍历完整个列表:
原Python代码翻译如下:
def is_sorted(xs): i = 1 while i < len(xs): if xs[i] < xs[i - 1]: return False i += 1 return True
实现方法
1. 简洁单行实现(利用Q内置函数)
Q语言的all函数支持短路求值,遇到第一个0b就停止计算,刚好符合我们的需求。结合列表切片做相邻元素比较,一行代码就能搞定:
isSorted:{all x[1:] >= x[:-1]}
测试验证:
isSorted a // 返回1b,说明列表有序 isSorted b // 返回0b,说明列表无序
2. 手动模拟循环逻辑(贴近Python写法)
如果想更贴近Python的循环思路,也可以用递归实现短路判断:
isSorted:{ $[count x <=1;1b; // 列表长度≤1直接判定为有序 x[1]<x[0];0b; // 发现第一个逆序立刻返回False .z.s x[1:]] // 递归检查剩余元素 }
这个版本同样会在发现逆序时立刻终止流程,不会继续遍历后续元素。
补充说明
- 两种实现都满足短路线性探测的要求,不用遍历整个列表就能提前得出结果。
- 第一种方法利用Q内置函数,代码最简洁,性能也最优,优先推荐使用。
内容的提问来源于stack exchange,提问作者Rol
相关产品推荐
相关产品推荐

