Core Concepts
Operations on Lists (Iterators & Amend)
Atoms, simple lists, mixed lists, indexing, slicing, and list operations.
Overview
Almost everything in q is a list. A table column is a list, a dictionary is a pair of lists, and a string is a list of characters. q's operators work on whole lists at once, so most q code is a few list operations chained together, with no loops.
This page covers the list operations you will reach for most often. The practice questions then combine them, along with the iterators from the Iterators page, to solve small problems.
Simple and Mixed Lists
A list whose items are all atoms of the same type is a simple list (also called a vector). Its type is a positive number:
p:103.2 103.21 103.22 103.15 102.15
type p / 9h — a float vectorA list with items of different types, or items that are themselves lists, is a mixed list (or general list), with type 0h:
type (1;`a;"x";2.5) / 0h
type (1 2;3 4) / 0h — a list of two listsSimple lists are stored compactly and are much faster to work with, so keep data in simple lists where you can.
A one-item list can't be typed as a literal. Use enlist:
enlist 5 / ,5 — the comma shows a one-item list
count enlist 5 / 1Making Lists
til 5 / 0 1 2 3 4
5#0 / 0 0 0 0 0
7#1 2 3 / 1 2 3 1 2 3 1 — Take repeats the list if it is too short
1 2,3 / 1 2 3 — JoinIndexing
Index with square brackets, or just by putting the index after the list. Indexes start at 0:
p 0 / 103.2
p[1 3] / 103.21 103.15 — a list of indexes returns a list
first p / 103.2
last p / 102.15Indexing past the end does not signal an error. It returns the null of the list's type:
p 10 / 0n
`a`b`c 5 / ` — the null symbolTaking and Dropping
# (Take) and _ (Drop) work from the front with a positive number and from the back with a negative one:
2#p / 103.2 103.21
-2#p / 103.15 102.15
2_p / 103.22 103.15 102.15
-2_p / 103.2 103.21 103.22cut splits a list into pieces of a given length:
2 cut til 7 / (0 1;2 3;4 5;,6)Searching and Filtering
? (Find) returns the index of the first match. If there is no match, it returns the length of the list:
p?103.22 / 2
p?999.0 / 5where turns a boolean list into the indexes of its 1b items. Indexing with those indexes filters the list:
p>103.18 / 11100b
where p>103.18 / 0 1 2
p where p>103.18 / 103.2 103.21 103.22Comparing Neighbours
Many problems compare each item with the one before it:
prev p / 0n 103.2 103.21 103.22 103.15
deltas p / 103.2 0.01 0.01 -0.07 -1deltas keeps the first item as it is, then gives the difference between each item and the one before. differ flags each item that is different from the one before:
l:`a`a`b`c`c`a
differ l / 101101b
distinct l / `a`b`cNulls
fills 1 0n 3 0n 5 / 1 1 3 3 5f — replace each null with the last non-null value
0^1 0n 3 0n 5 / 1 0 3 0 5f — replace nulls with a fixed valueSorting
asc 3 1 2 / `s#1 2 3
desc 3 1 2 / 3 2 1
iasc 3 1 2 / 1 2 0 — the indexes that would sort the listasc adds the sorted attribute `s# to its result (see Attributes).
Nested Lists
A list of lists can be indexed at depth. Leaving an index out selects everything at that level:
n:(1 2 3;4 5 6)
n[1;2] / 6
n[;0] / 1 4 — the first item of each list
raze n / 1 2 3 4 5 6Arithmetic on Whole Lists
Arithmetic works item by item. An atom is paired with every item, and two lists must be the same length:
1 2 3 + 10 / 11 12 13
1 2 3 + 10 20 30 / 11 22 33Adding lists of different lengths, such as 1 2 3 + 10 20, signals 'length.
Changing Items (Amend)
Assigning to an index changes the list in place:
x:10 20 30
x[1]:99
x / 10 99 30@ (Amend At) returns a changed copy, and leaves the original alone. Give it the list, the indexes, a function and its argument:
@[10 20 30;0 2;+;1] / 11 20 31
@[p;0;:;100.0] / 100 103.21 103.22 103.15 102.15 — ":" means "replace with"
p / 103.2 103.21 103.22 103.15 102.15 — unchangedAggregating
sum p / 514.93
max p / 103.22
avg p / 102.986To apply a function to each item of a list, or to fold a list into a running total, see the Iterators page.