前言
字典是由键列表和值列表(Key-Value)之间的显式关联映射。这两个列表必须具有相同的长度,并且键列表应该是唯一的集合。
一、字典的定义
字典是键列表和值列表之间的关联。从逻辑上讲,它也可以被视为键值对,但它在物理上存储为一对列表。
- 字典的定义
字典用“!”来定义:keys !values。字典的type类型值为99h
q)10 20 30!1.1 2.2 3.3 /定义一个字典
10| 1.1
20| 2.2
30| 3.3
q)`a`b`c!100 200 300 /定义一个字典
a| 100
b| 200
c| 300
q)"abc"!10 20 30 /定义一个字典
a| 10
b| 20
c| 30
q)10 20 30!"abc" /定义一个字典
10| a
20| b
30| c
q)`a`b`c!1 2 /字典的key和value的长度必须一样
'length
q)`a`b!1 2 3 /字典的key和value的长度必须一样
'length
q)D:`a`b`c!10 20 30
q)type D /字典的类型值为99h
99h
q)(`zhangsan`s001; `lisi`s002; `wangwu`s003)!98 100 99 /创建复合字典
zhangsan s001| 98
lisi s002| 100
wangwu s003| 99
q)1001 1002 1003!(`zhangsan`class01; `lisi`class02; `wangwu`class03) /创建复合字典
1001| zhangsan class01
1002| lisi class02
1003| wangwu class03
字典没有强制key值为唯一的,但是作为KDB数据库,为了提高计算和处理效率,还是建议key值设置为唯一值比较好,我们可以用“`u#”这个属性来查看key值是否唯一。同时key和value列表中元素的顺序很重要,就像列表的位置顺序很重要一样。尽管无论顺序如何,I / O分配和相关映射都是等效的,但不同排序的字典并不相同。
q)D:`a`b`c`a!10 20 30 40 /创建一个字典,key值并不唯一
q)D
a| 10
b| 20
c| 30
a| 40
q)D:(`a`b; `c`d`e; enlist `f)!10 20 30 /创建一个复合类型的字典
q)D
`a`b | 10
`c`d`e| 20
,`f | 30
q)D1:`a`b`c!(10 20; 30 40 50; enlist 60) /创建一个复合类型的字典
q)D1
a| 10 20
b| 30 40 50
c| ,60
q)D3:`a`b`c!("string"; 10 20 30; `zhangsan) /创建一个复合类型的字典
q)D3
a| "string"
b| 10 20 30
c| `zhangsan
q)(`u#`a`b`c)!10 20 30 /通过“`u#”属性来检查字典的key值是否唯一
a| 10
b| 20
c| 30
q)(`u#`a`b`c`a)!10 20 30 40 /使用“`u#”检查key值不唯一时,返回'u-fail错误
'u-fail
q)(`a`b`c!10 20 30)~`a`c`b!10 30 20 /有相同的key和value值,但是顺序不同的两个字典是不相等的
0b
- 空字典和单行字典
有时候根据需要,我们会创建一个空字典或者是单行字典,具体创建方式如下:
q)()!() /创建一个未指定类型的空字典
q)(`symbol$())!`float$() /创建一个指定类型的空字典
q)`x!42 /当一个字典只有一行数据时,这种创建方式行不通
`x!42
q)type `x!42 /通过类型值查询返回的不是99h,因此不是字典类型
-20h
q)(enlist `x)!enlist 42 /单行字典的具体创建方式
x| 42
q)type (`symbol$())!(`float$())
99h
q)type (enlist `x)!enlist 42
99h
二、字典的基本操作
字典的增、删、改、查与其他操作也非常的方便,由于字典是有列表组成,因此很多操作上与列表非常的相似。
- 字典的查找
字典的查找方式有多种方式,具体参考如下:
q)d:`a`b`c!10 20 30 /创建一个字典
q)key d /查询字典中所有的key值
`a`b`c
q)value d /查询字典中所有的value值
10 20 30
q)count d /计算字典的行数
3
q)d[`a] /查询字典中key为`a的value值
10
q)d `b /查询字典中key为`b的value值
20
q)d[`x] /查询字典中key为`x的value值,若查询的值不存在则返回0N
0N
q)d[`a`b] /同时查询字典中key为`a`b的value值
10 20
q)d `a`b /同时查询字典中key为`a`b的value值
10 20
q)kv:`a`b
q)d[kv] /通过变量查询方式
10 20
q)d?10 /?号用于反向查找,通过value值查询key值
`a
q)d?`a /?号不能用于通过key查找value值
'type
q)d?40 /同样反向查找不存在key值时返回一个“`”符号
`
q)d1:`a`b`c`a!10 20 30 10 /创建一个key值不唯一的字典
q)d1
a| 10
b| 20
c| 30
a| 10
q)d1?10 /可以通过?号反向查找
`a
q)d1:`a`b`c`a!10 20 30 40 /创建一个key值不唯一的字典
q)d1?40 /可以通过?反向查找
`a
q)d1[`a] /正向查找时,当有重复的key值只返回第一个key对应的value值
10
q)where 10=d1 /查询字典d1中所有value为10的key值
,`a
q)d1:`a`b`c`a!10 10 20 30
q)where 10=d1 /查询字典d1中所有value为10的key值
`a`b
q)d:(`a`b; `c`d`e; enlist `f)!10 20 30 /创建一个复合字典
q)d
`a`b | 10
`c`d`e| 20
,`f | 30
q)d[`f] /复合字典的查询方式
30
q)d[`a] /复合字典的查询方式,key值必须全部对应才能查到对应的value值
0N
q)d[`a`b] /复合字典的查询方式,key值必须全部对应才能查到对应的value值
10
q)d?10 /复合字典的反向查找
`a`b
q)d:`a`b`c!(10 20; 30 40 50; enlist 60)
q)d[`b] /复合字典的正向查找
30 40 50
q)d?30 40 50 /复合字典的正向查找
`b
q)d?30 /复合字典的反向查找也必须所有value值对应,因此这里必须为30 40 50
`
q)d?60
`c
q)d2:(1 2; 3 4 5; 6; 7 8)!10 20 30 40
q)d2
1 2 | 10
3 4 5 | 20
6 | 30
7 8 | 40
q)d2 1 2 /复合字典的正向查找
10
q)d2 6 /由于key值中的6不是enlist创建方式,因此这里查找不到对应的结果
0N
q)d2 enlist 6 /由于key值中的6不是enlist创建方式,因此这里查找不到对应的结果
0N
q)d3:10 20 30 40!(1 2; 3 4 5; 6; 7 8)
q)d3
10| 1 2
20| 3 4 5
30| 6
40| 7 8
q)d3 ? 3 4 5 /复合字典的反向查找也必须所有value值对应,因此这里必须为30 40 50
20
q)d3 ? 6 /由于value值中的6不是enlist创建方式,因此这里查找不到对应的结果
0N
q)d? enlist 6 /由于key值中的6不是enlist创建方式,因此这里查找不到对应的结果
`
- 字典value值的修改
与列表一样,我们可以通过:号来修改字典中的value值,d[key]:value。
q)d:`a`b`c!10 20 30
q)d
a| 10
b| 20
c| 30
q)d[`a]:50 /将key为`a的value值修改为50
q)d
a| 50
b| 20
c| 30
3. 字典key-value值的删除
q)d:`a`b`c!10 20 30
q)d
a| 10
b| 20
c| 30
q)`a`c _ d /删除字典中key值为`a`c的数据值,返回的结果不包含删除的值,但是字典d中的值还是存在
b| 20
q)d /查询字典d的值发现删除的值还在
a| 10
b| 20
c| 30
q)d: `a`c _ d /通过该方式可以实现真正意义上的字典数据删除,后面还有提到通过传递字典名称的方式删除
q)d /此时查询字典中的值就不存在已经删除的值了
b| 20
q)d:`a`b`c!10 20 30
q)d
a| 10
b| 20
c| 30
q)`x`a _ d /当删除字典中不存在的值时,也不会报错
b| 20
c| 30
q)`a`c cut d /使用cut内置函数删除字典中的值
b| 20
q)d _ `b /另外一种删除字典中的值的方式
a| 10
c| 30
- 字典key-value值的增加
与字典的修改相似,当要修改的key值不存在时,会自动在字典的末尾追加修改的值,同时只能在末尾增加新的值,不能在中间插入。但是可以通过其他办法在中间插入。
q)d:`a`b`c!10 20 30
q)d
a| 10
b| 20
c| 30
q)d[`a]:50 /修改字典的数据
q)d
a| 50
b| 20
c| 30
q)d[`e]:40 /向字典中增加的数据,默认只能插在字典的最后
q)d
a| 50
b| 20
c| 30
e| 40
- 提取字典中的值
我们也可以同时提取字典中的多个值组成一个新的字典
q)d:`a`b`c!10 20 30
q)d `a`c /返回的值不是字典,而是列表
10 30
q)`a`c#d /提取key值为`a`c的值组成新的子字典
a| 10
c| 30
- 字典的+、-、*、%操作与关系运算
两个字典也可以进行加、减、乘、除操作,但是需要注意的是字典key值不同时加减乘除操作的结果。
q)d1:`a`b`c!1 2 3
q)d2:`a`b`c!10 20 30
q)d1+d2 /两个key值相同字典相加
a| 11
b| 22
c| 33
q)d1-d2 /两个key值相同字典相减
a| -9
b| -18
c| -27
q)d1*d2 /两个key值相同字典相乘
a| 10
b| 40
c| 90
q)d1%d2 /两个key值相同字典相除
a| 0.1
b| 0.1
c| 0.1
q)d1:`a`b`c!1 2 3
q)d2:`b`c`d!20 30 40
q)d1+d2 /两个不同key值字典相加
a| 1
b| 22
c| 33
d| 40
q)d1-d2 /两个不同key值字典相减
a| 1
b| -18
c| -27
d| -40
q)d1*d2 /两个不同key值字典相乘
a| 1
b| 40
c| 90
d| 40
q)d1%d2 /两个不同key值字典相除
a| 1
b| 0.1
c| 0.1
d| 40
q)d1:`a`b`c!1 2 3
q)d2:`d`e`f!10 20 30
q)d1+d2 /两个完全不同key值字典相加
a| 1
b| 2
c| 3
d| 10
e| 20
f| 30
q)d1-d2 /两个完全不同key值字典相减
a| 1
b| 2
c| 3
d| -10
e| -20
f| -30
q)d1*d2 /两个完全不同key值字典相乘
a| 1
b| 2
c| 3
d| 10
e| 20
f| 30
q)d1%d2 /两个完全不同key值字典相除
a| 1
b| 2
c| 3
d| 10
e| 20
f| 30
q)d1:`a`b!1 2
q)d2:`d`e`f!10 20 30
q)d1+d2 /两个完全不同key值且长度也不相等的字典相加
a| 1
b| 2
d| 10
e| 20
f| 30
q)d1-d2 /两个完全不同key值且长度也不相等的字典相减
a| 1
b| 2
d| -10
e| -20
f| -30
q)d1*d2 /两个完全不同key值且长度也不相等的字典相乘
a| 1
b| 2
d| 10
e| 20
f| 30
q)d1%d2 /两个完全不同key值且长度也不相等的字典相除
a| 1
b| 2
d| 10
e| 20
f| 30
q)(`a`b`c!10 20 30)=`b`c`d!20 300 400 /判断两个字典中的键值是否相等
a| 0
b| 1
c| 0
d| 0
q)(`a`b`c!0N 20 30)=`b`c`d!20 300 0N /判断两个字典中的键值是否相等,0N与0N值相等
a| 1
b| 1
c| 0
d| 1
q)(`a`b`c!10 20 30)<`b`c`d!20 300 400 /判断两个字典中的键值的大小
a| 0
b| 0
c| 1
d| 1
q)(`a`b`c!10 20 30)>`b`c`d!20 300 400 /判断两个字典中的键值的大小
b| 0
c| 0
d| 0
a| 1
q)(`a`b`c!10 20 30)>=`b`c`d!20 300 400 /判断两个字典中的键值的大小
a| 1
b| 1
c| 0
d| 0
q)(`a`b`c!10 20 30) = `c`d`e! 30 40 50 /判断两个字典中的键值是否相等,具体值与0N值不相等
a| 0
b| 0
c| 1
d| 0
e| 0
- 字典的合并
我们也可以通过不同的方式合并两个字典,分为,号合并与^合并,合并方式不同,最终得到的结果也有差异,具体如下:
q)d1:`a`b`c!10 20 30
q)d2:`c`d!300 400
q)d1,d2 /字典d1与字典d2的合并,右边覆盖左边的值(d2覆盖d1)
a| 10
b| 20
c| 300
d| 400
q)d2,d1 /字典d2与字典d1的合并,右边覆盖左边的值(d1覆盖d2)
c| 30
d| 400
a| 10
b| 20
q)d1:`a`b`c!10 0N 30
q)d2:`b`c`d!200 0N 400
q)d1,d2 /字典d1与字典d2的合并,右边覆盖左边的值(d1覆盖d2)
a| 10
b| 200
c|
d| 400
q)d1^d2 /字典d1与字典d2的^合并,右边填充左边的空值(不是空值的与,号合并相同)
a| 10
b| 200
c| 30
d| 400
q)d1,d2 /字典d1与字典d2的合并,右边覆盖左边的值(d2覆盖d1)
a| 10
b| 200
c|
d| 400
q)d2^d1 /字典d2与字典d1的^合并,右边填充左边的空值(不是空值的与,号合并相同)
b| 200
c| 30
d| 400
a| 10
三、列表字典
列表字典将是表的一个数据基础,后续会提到表的时候可以作对比。列表的字典的key和value都可以是列表,定义如下:
C1…Cn!(V1…Vn)
其中Ci和Vi都可以是简单列表
列表字典可以被视为二维实体,在第一维中按名称检索,在第二维中按列在value值内检索。
仅指定key名称将检索相应的value,然后可以按位置对其进行索引。
仅指定value索引将检索切片字典,最后返回的结果为字典。
q)`c1`c2!(`a`b`c; 10 20 30) /创建列表字典
c1| a b c
c2| 10 20 30
q)`c1`c2!(`a`b`c; 10) /创建列表字典
c1| `a`b`c
c2| 10
q)Students:`name`score!(`zhangsan`lisi`wangwu;98 99 100) /创建列表字典
q)Students
name | zhangsan lisi wangwu
score| 98 99 100
q)Students[`name] /列表字典的查询
`zhangsan`lisi`wangwu
q)Students[`score] /列表字典的查询
98 99 100
q)Students[`name][1]
`lisi
q)Students[`score][1]
99
q)Students[`score;1]
99
q)Students[`name;1]
`lisi
q)Students[;1] /返回结果为对应的字典
name | `lisi
score| 99
q)Students[;]
name | zhangsan lisi wangwu
score| 98 99 100
q)Students[`name;]
`zhangsan`lisi`wangwu
q)Students[;1 2] /返回对应的字典
name | lisi wangwu
score| 99 100
四、列表字典的转置
我们也可以将列表字典进行类似于矩阵的转置操作,但是普通字典是不能进行flip操作。转置后相应的查询也发生了变化
q)dc:`c1`c2!(`a`b`c; 10 20 30)
q)dc
c1| a b c
c2| 10 20 30
q)flip dc /列字典的转置
c1 c2
-----
a 10
b 20
c 30
q)t:flip dc
q)t
c1 c2
-----
a 10
b 20
c 30
q)dc[`c1; 0]
`a
q)dc[`c1; 1]
`b
q)dc[`c1; 2]
`c
q)t[0; `c1]
`a
q)t[1; `c1]
`b
q)t[2; `c1]
`c
q)dc[`c1;]
`a`b`c
q)t[;`c1]
`a`b`c
q)dc[;0]
c1| `a
c2| 10
q)t[0;] /转置后返回的仍然是一个字典
c1| `a
c2| 10