Send Feedback
Skip to content

How to Work with Dictionaries

This page provides an introduction on how to work with dictionaries in KDB-X.

Overview

Syntax

A dictionary is a mapping from a list of keys to a list of values.

Syntax:

k!v    ![k;v]

Where:

  • Returns a dictionary in which k is the key and v is the value
  • The keys k and values v are same-length lists
  • The keys k should be unique (no duplicates), but no error is signalled if duplicates are present. However, operations on dictionaries with duplicate keys are undefined
  • Items of k and v can be of any datatype, including dictionaries or tables

Keywords key and value return the key and value lists respectively.

All dictionaries have type 99h.

Example:

q)show d1:`tom`dick`harry!1040 59 27
tom  | 1040
dick | 59
harry| 27
q)key d1
`tom`dick`harry
q)value d1
1040 59 27
q)type d1
99h

If you know the keys are unique you can set the u attribute on them, as below. The dictionary will then function as a hash table, and indexing will be faster.

q)show d2:(`u#`a`b`c)!100 200 300
a| 100
b| 200
c| 300
q)key d2
`u#`a`b`c

Empty and singleton dictionaries

Just like a list, a dictionary may be empty or have a single item.

But its key and value must still be lists. Therefore, you must enlist atoms for a singleton dictionary.

q)()!()                          / general empty dictionary
q)(`symbol$())!`float$()         / typed empty dictionary

q)show sd:(enlist `a)!enlist 1   / singleton dictionary
a| 1
q)key sd
,`a
q)value sd
,1

Dictionary literal syntax

Dictionary literal syntax was introduced as part of kdb+ 4.1.

With dictionary literals, you can concisely define dictionaries, and it removes the need to enlist atoms for singleton dictionaries:

q)enlist[`aaa]!enlist 123   / 4.0 syntax
aaa| 123 

q)([aaa:123])               / 4.1 literal syntax
aaa| 123 

This syntax follows rules consistent with list and table literal syntax:

q)([0;1;2])                 / implicit key names (when omitted, default key names are assigned)
x | 0
x1| 1
x2| 2

q)d:([a:101;b:]);d 102      / missing values create projections
a| 101
b| 102

q)d each `AA`BB`CC          / create a list of dictionaries (table) via projection
a   b
------
101 AA
101 BB
101 CC

Similar to list literal syntax (;..), omission of values results in projection:

q)([k1:;k2:])[1;"a"]
k1| 1
k2| "a"

Lookup

To find the output value corresponding to an input key, we look up the key. Lookup uses the same notation as indexing into a list:

q)k:`a`b`c`d`e
q)v:10 20 30 40 50
q)show dict:k!v
a| 10
b| 20
c| 30
d| 40
e| 50

q)dict[`d`b]         / indexing
40 20
q)v[3 1]
40 20

q)dict `d`b          / brackets not necessary for indexing
40 20
q)v 3 1
40 20

q)v 5               / indexing out of domain works as for lists
0N                  / returns a null of same type of the first value item
q)dict `x
0N

Reverse lookup

Reverse lookups can be done on dictionaries using keywords where and find.

Example:

q)show d:`a`b`c`d!10 20 30 10
a| 10
b| 20
c| 30
d| 10

q)where d=20        / where  
,`b
q)where d=40
`symbol$()
q)where d=10
`a`d

q)d?30              / find
`c
q)d?40              / indexing out of domain works as for lists
`                   / returns a null of same type of the first key item
q)d?10
`a                  / unlike where, find only returns the first match

Taking and dropping from a dictionary

Dictionaries are ordered, so you can take and drop items from either end of them.

Example:

q)show d:`a`b`c`d!10 20 30 10
a| 10
b| 20
c| 30
d| 10

q)-2#d
c| 30
d| 10

q)-1 _ d
a| 10
b| 20
c| 30

You can also take and drop selected items:

q)`b`d#d
b| 20
d| 10

q)`b`x _ d
a| 10
c| 30
d| 10

Joining dictionaries

The Join operator (,) merges two dictionaries.

Join on dictionaries has upsert semantics for common keys. If a key exists in both dictionaries, the value from the right-hand dictionary will overwrite the value from the left dictionary. New keys are appended to the end.

Example:

q)show d1:`a`b`c!10 20 30
a| 10
b| 20
c| 30
q)show d2:`c`d!400 500
c| 400
d| 500
q)d1,d2
a| 10
b| 20
c| 400
d| 500

Column dictionaries

When a dictionary’s value items are all same-length lists, it is called a column dictionary. Column dictionaries are the foundation for tables.

Example:

q)show bd:`name`dob`sex!(`jack`jill`john;1982.09.15 1984.07.05 1990.11.16;`m`f`m)
name| jack       jill       john
dob | 1982.09.15 1984.07.05 1990.11.16
sex | m          f          m

q)count each value bd
3 3 3

Flip a column dictionary and the result is a table:

q)flip bd
name dob        sex
-------------------
jack 1982.09.15 m
jill 1984.07.05 f
john 1990.11.16 m

q)type flip bd
98h

Step dictionaries

A step dictionary is a dictionary with the sorted attribute applied. This will have the effect of referencing the preceding dictionary entry instead of returning a null for keys which don't exist.

Note

The sorted attribute needs to be applied to the keys of the dictionary, as well as to the dictionary as a whole for it to function as a step dictionary. If the keys are unsorted, 's-fail will be thrown when you try to create a step dictionary.

An as-of join is an example of a step dictionary - it joins the prevailing value to the time field in the join.

Example:

q)dict:`s#1 10 5!0.2 0.5 0.75        // unsorted keys, 's-fail
's-fail
  [0]  dict:`s#1 10 5!0.2 0.5 0.75
              ^
q)show dict:`s#1 5 10!0.2 0.5 0.75
1 | 0.2
5 | 0.5
10| 0.75
q)0N!dict;                          // `s# applied to the keys as well as dict itself
`s#`s#1 5 10!0.2 0.5 0.75
q)dict 1
0.2
q)dict 3
0.2
q)dict 5
0.5
q)dict 6
0.5
q)dict 99
0.75

Summary

In this guide, you learned how to:

  • Create empty, singleton and multiplex dictionaries
  • Create dictionaries using dictionary literal syntax
  • Do lookups and reverse lookups on dictionaries
  • Take and drop from dictionaries
  • Join dictionaries
  • Flip column dictionaries to create tables
  • Create and lookup step dictionaries

For additional detail on dictionaries, check out Q for Mortals §5. Dictionaries

You now have the essential skills to work with dictionaries in KDB-X.