- 字典基础1. 定义字典是key-values pairs, 但是在q中,字典是按照list来存储的。字典的创建使用操作符!,读作bang :) 所有的字典类型都是99h。q)10 20 30!1.1 2.2 3.310| 1.120| 2.230| 3.3q)
a
bc!100 200 300a| 100b| 200c| 300可以使用操作符key, value, count来分别获取字典的键、值和个数。尽管q语言不强制键的唯一性(historical mistake),但是却对每个输入值都提供唯一的输出,只有第一次出现的key会被看到。当你知道字典的键是unique的时候,可以使用命令
u#将字典转换为哈希表,这样与原来的线性搜索相比,会提高查找的速度。q)(u#
ab
c)!10 20 30注意:与传统语言不一样,不同顺序的字典在q中是不等的。q)(a
bc!10 20 30)~
ac
b!10 30 200b2. 空和单例字典 空字典:()!()带类型的空字典:symbol$()!
float$()单例字典,必须要使用enlist形式先生成一个list,否则会报错q)(enlist x)!enlist 42x| 423. 查找使用中括号或者并列的形式:q)d:
ab
c!10 20 30q)d[a]10q)d
b20当查找值不在字典的键表中时,返回值列表中初始值类型的Null值:q)d[x]0N4. 逆向查找 使用? 与列表类似,?返回值在字典中对应的键。q)d:
ab
ca!10 20 30 10q)d?10
a当查找的值不在字典的值列表中时,返回键列表中初始值类型的Null值:q)d:a
bc
a!10 20 30 10q)d?405. 字典和列表 可以通过字典来表示一个稀疏列表:q)d1:0 100 500000!10 20 30q)d2:0 99 1000000!100 200 300q)d1+d20 | 110100 | 20500000 | 3099 | 2001000000| 3006. 不唯一的键和值 如之前所说,当键不唯一时,会返回第一个出现时的值:q)ddup:
ab
ac!10 20 30 20q)ddup[
a]10逆向查找同理:q)ddup?30aq)ddup?20
b7. Non-simple 键 和 值键和值是嵌套的列表:q)d:(a
b; c
de; enlist
f)!10 20 30q)d f30q)d?20
cd
eq)d:a
bc!(10 20; 30 40 50; enlist 60)q)d
b30 40 50q)d?30 40 50bq)d?enlist 60注意,对单个元素的键或值要单独对其生成一个列表(enlist),否则会有如下的问题:q)dwhackey:(1 2; 3 4 5; 6; 7 8)!10 20 30 40 / atom 6 is whackq)dwhackey 1 210q)dwhackey 60Nq)dwhackval:10 20 30 40!(1 2; 3 4 5; 6; 7 8) / atom 6 is whackq)dwhackval?3 4 520q)dwhackval?60N会导致查找失败,返回Null值。2. 字典操作1. Amend 和 Upsert update:q)d:
ab
c!10 20 30q)d[b]:42insert:q)d:
ab
c!10 20 30q)d[x]:42在q语言中,update/insert操作被称为upsert操作。2. 提取子字典使用提取操作符#,左运算元为子字典的键,右运算元为原始字典。 另外,当原始字典有重复键时,只会提取第一次出现的键:q)ddup:
ab
ac!10 20 30 20q)
ac#ddupa| 10c| 203. 删除 使用操作符_, 用法与#类似,但需要注意_前后要加空格。q)d:
ab
c!10 20 30q)a
c _ db| 20q)(enlist b) _ d删除全部键值对会得到一个带类型的空字典:q)d:
ab
c!10 20 30q)a
bc _ dq)-3!
ab
c _ d"(symbol$())!
long$()“操作符cut与_在字典上的效果相同。另外一个很少用的用法是,字典在_的左边,_右运算元为一个单一的键,表示字典删除这个键:q)d _ ba| 10c| 304. 字典上的基础运算一些常见的基础运算如下例所示,非常容易理解q)d:
ab
c!10 20 30q)neg da| -10b| -20c| -30字典的加法: 相同键值进行加法操作,不同键值保留下来q)d1:a
bc!1 2 3q)d2:
bc
d!20 30 40q)d1+d2a| 1b| 22c| 33d| 405. join,使用,进行合并字典的操作,由于q语言是right to left特性的,所以合并的两个字典如果有相同的键值,那么右边的会保留下来。q)d1:a
bc!10 20 30q)d2:
cd!300 400q)d1,d2a| 10b| 20c| 300d| 400因此,字典合并时,前后顺序很重要。6. Coalesce ^ 这种合并方式类似于,合并, 但与其不同的是,当^右边右边项值为Null时不覆盖左边项,见下例:q)d1:
ab
c!10 0N 30q)d2:b
cd!200 0N 400q)d1^d2a| 10b| 200c| 30d| 400q)d1,d2a| 10b| 200c|d| 4007. 算术和相等运算符 对于相等性比较,由于null代表缺失值,所以所有的null值会被认为是相等的。q)(
ab
c!10 20 30)=b
cd!20 300 400a| 0b| 1c| 0d| 0q)(
ab
c!0N 20 30)=b
cd!20 300 0Na| 1b| 1c| 0d| 1q)(
ab
c!10 20 30)<b
cd!20 300 400a| 0b| 0c| 1d| 13. 列字典列字典(Column Dictionary)是表(Table)的基础。1. 定义和术语一个一般的列字典具有如下的形式:c1...cn!(v1;...;vn)其中ci是symbol类型,vi是具有相同长度的列表。通常vi均为简单列表。2. 简单例子q)travelers:
nameiq!(
DentBeeblebrox
Prefect;42 98 126)q)travelersname| Dent Beeblebrox Prefectiq | 42 98 126索引:q)travelers[name; 1]
Beeblebroxq)travelers[iq; 2]126单列的字典:q)dc1:(enlist
c)!enlist 10 20 30q)dc1c| 10 20 304. 列字典的翻转q)dc:c1
c2!(a
bc; 10 20 30)q)dcc1| a b cc2| 10 20 30q)t:flip dcq)tc1 c2-----a 10b 20c 30索引:q)dc[
c1; 0]aq)dc[
c1; 1]bq)dc[
c1; 2]cq)t[0;
c1]aq)t[1;
c1]bq)t[2;
c1]`cUnlike the case of transposing rectangular lists, transposing a column dictionary does not physically re-arrange data.(翻转并不会改变数据的存储)