# lists and sequences -- a detailed overview of lists and sequences in Macaulay2

This page gives an overview of the use of lists of all types, including:

basic lists (of class BasicList),
visible lists (of class VisibleList),
lists (of class List),
sequences (of class Sequence),
arrays (of class Array), and
mutable lists (of class MutableList).

The sections of the overview are, in order:

Creating lists; kinds of lists.
Elements and indexing.
Nested lists.
Ranges and repetitions.
Manipulating lists and sequences.
Mapping over lists.
Conditional expressions; selecting elements matching a criterion.

Links to individual documentation pages for the functions described in this article are collected in an alphabetized list at the very end of the page.

Creating lists; kinds of lists.

To create a list, use curly braces around a comma-separated series of elements.

 ```i1 : L = {a,b,c,d,e} o1 = {a, b, c, d, e} o1 : List```

Sequences are created and displayed using parentheses instead of braces.

 ```i2 : S = (a,b,c,d,e) o2 = (a, b, c, d, e) o2 : Sequence```

Sequences are implemented in a more efficient way than lists, since a sequence is created every time a function is called with more than one argument. On the other hand, parentheses are also used for grouping algebraic expressions. This complicates some tasks, such as creating a sequence of length 1.

 ```i3 : () o3 = () o3 : Sequence``` ```i4 : (1,2) o4 = (1, 2) o4 : Sequence``` ```i5 : (1) o5 = 1```

The functions toList and toSequence, which convert between lists and sequences, may be useful here.

 ```i6 : toSequence {1} o6 = 1 : (1) o6 : Sequence```

Lists and sequences can be used as vectors, provided their elements are the sorts of things that can be added and mutliplied.

 ```i7 : 10000*{3,4,5} + {1,2,3} o7 = {30001, 40002, 50003} o7 : List```

An array is another type of list, created and displayed using square brackets. Unlike lists and sequences, arrays can’t be used as vectors. Their main use is notational; for example, they appear in the construction of polynomial rings.

 ```i8 : v = [1,2,3] o8 = [1, 2, 3] o8 : Array``` ```i9 : ZZ[a,b,c] o9 = ZZ[a, b, c] o9 : PolynomialRing```

Lists, sequences, and arrays are the three examples of what we call visible lists, which constitute the class VisibleList. Many functions are defined to act uniformly on visible lists. There is a type of list more general than a visible list, which we call a BasicList. Basic lists are a secure choice for defining new datatypes, since the many functions that act on visible lists do not act on basic lists. Here we illustrate how to create a new type of basic list, in this case called Container.

 ```i10 : Container = new Type of BasicList o10 = Container o10 : Type``` ```i11 : t = new Container from {a,b} o11 = Container{a, b} o11 : Container```

We can then declare a new method for the operator ++ that will join two Containers:

 `i12 : Container ++ Container := join;` ```i13 : t ++ t o13 = Container{a, b, a, b} o13 : Container```

Basic lists are normally immutable; that is, no element can be replaced, added, or removed. (Functions like append, and the many others described in the Manipulating lists and sequences section, will return a new list in Macaulay2, as a general rule, rather than modify the existing list.)

However, there is a certain type of basic list, called a mutable list (of class MutableList), whose elements can be changed. This allows the possibility of creating circular structures that would cause a print routine to go into an infinite loop. To avoid such infinite loops, the contents of mutable lists are not printed. Instead, use peek to display the elements in a controlled way.

 ```i14 : A = new MutableList from {a,b,c} o14 = MutableList{...3...} o14 : MutableList``` ```i15 : peek A o15 = MutableList{a, b, c}``` `i16 : A#2 = 1234;` ```i17 : A o17 = MutableList{...3...} o17 : MutableList``` ```i18 : peek A o18 = MutableList{a, b, 1234}```

Because the contents of mutable lists are not printed, they can be used as containers for big things one doesn’t want to print. Although any mutable list can be used in this way, there is a a special type of mutable list called a Bag, which is designed for this purpose. When printed, the bag displays only a little information about its contents.

 ```i19 : r = Bag {100!}; r o20 = -*a bagged integer*- o20 : Bag``` ```i21 : q = Bag {1/100!}; q o22 = -*a bagged rational number*- o22 : Bag``` ```i23 : unbag q o23 = ----------------------------------------------------------------------- 93326215443944152681699238856266700490715968264381621468592963895217599 ======================================================================= 1 ----------------------------------------------------------------------- 99322991560894146397615651828625369792082722375825118521091686400000000 ======================================================================= ---------------- 0000000000000000 o23 : QQ```

The hierarchy of types mentioned above is summarized here using showStructure:

 ```i24 : showStructure(List,Sequence,Array,Container,MutableList,Bag,BasicList) o24 = Thing : BasicList : Container MutableList : Bag VisibleList : Array List Sequence o24 : Descent```

Elements and indexing.

We retrieve the length of a list with the operator # or with the function length.

 `i25 : L = {926, 621, 429, 67, 594, 904, 264, 18, 35, 961};` ```i26 : #L o26 = 10``` ```i27 : length L o27 = 10```

The expression L#n returns the nth element of L. The elements are numbered consecutively starting with 0. Alternatively, they are numbered consecutively ending with -1.

 ```i28 : L#0 o28 = 926``` ```i29 : L#2 o29 = 429``` ```i30 : L#-1 o30 = 961```

The _ operator is similar to #, except that it can also take a list or range of indices. However, it may only be used with visible lists.

 ```i31 : L_1 o31 = 621``` ```i32 : L_{3,6} o32 = {67, 264} o32 : List```

The functions first and last retrieve the first and last elements of a list.

 ```i33 : first L o33 = 926``` ```i34 : last L o34 = 961```

Omitting an element of a list causes the symbol null to be inserted in its place. When the value of an expression is null, like when we ask for A#2 in the next example, the output line doesn’t appear at all.

 ```i35 : A = {3,4,,5} o35 = {3, 4, , 5} o35 : List``` ```i36 : peek A o36 = {3, 4, null, 5}``` `i37 : A#2`

Ranges and repetitions.

The operator .. can be used to create sequences of numbers, sequences of subscripted variables, and so on.

 ```i38 : 1 .. 5, x_1 .. x_5, a .. e o38 = ((1, 2, 3, 4, 5), (x , x , x , x , x ), (a, b, c, d, e)) 1 2 3 4 5 o38 : Sequence```

The operator ZZ : Thing creates a sequence by replicating an element a given number of times.

 ```i39 : 12:a o39 = (a, a, a, a, a, a, a, a, a, a, a, a) o39 : Sequence```

Replicating something once is another way to create a sequence of length 1, which cannot be entered by simply typing parentheses.

 ```i40 : 1:a o40 = 1 : (a) o40 : Sequence```

Both .. and : produce sequences, and may not behave as expected with respect to nesting. For instance, to create the list {3, 4, 5, 6, 9, 12, 12, 12}, the following command will not work:

 ```i41 : A = {3 .. 6, 9, 3:12} o41 = {(3, 4, 5, 6), 9, (12, 12, 12)} o41 : List```

Instead, we get a list of length 3, some of whose elements are sequences. This is easily resolved with splice.

 ```i42 : A = splice {3..6, 9, 3:12} o42 = {3, 4, 5, 6, 9, 12, 12, 12} o42 : List```

However, many operators and functions will automatically splice lists for you. Two examples are the array of variables defining a polynomial ring, and the indices passed to the _ operator.

 ```i43 : QQ[a..c,x_1..x_4] o43 = QQ[a, b, c, x , x , x , x ] 1 2 3 4 o43 : PolynomialRing``` ```i44 : L_{1..3,-3..-1} o44 = {621, 429, 67, 18, 35, 961} o44 : List```

Nested lists.

When the elements of a list are themselves lists, we call it a nested list.

 ```i45 : A = {{a,b,c},{d,{e,f}}} o45 = {{a, b, c}, {d, {e, f}}} o45 : List``` ```i46 : #A o46 = 2``` ```i47 : #(first A) o47 = 3```

One level of nesting may be eliminated with flatten.

 ```i48 : flatten A o48 = {a, b, c, d, {e, f}} o48 : List```

The function splice acts analogously on sequences, removing those pairs of parentheses that are one level inward.

 ```i49 : splice (a, (b, c), (d, (e, f, (g, h))) ) o49 = (a, b, c, d, (e, f, (g, h))) o49 : Sequence```

To remove all layers of nesting at once, use deepSplice.

 ```i50 : deepSplice (a, (b, c), (d, (e, f, (g, h))) ) o50 = (a, b, c, d, e, f, g, h) o50 : Sequence```

A table is a list whose elements are lists all of the same length. The inner lists are regarded as rows when the table is displayed as a two-dimensional array with MatrixExpression.

 ```i51 : T = {{a,1},{b,2},{c,3}} o51 = {{a, 1}, {b, 2}, {c, 3}} o51 : List``` ```i52 : isTable T o52 = true``` ```i53 : MatrixExpression T o53 = | a 1 | | | | b 2 | | | | c 3 | o53 : Expression of class MatrixExpression```

The function table can be used to create a table (doubly nested list) from two lists and a function of two arguments. It applies the function consecutively to each element from the first list paired with each element from the second list, so the total number of evaluations of the function is the product of the lengths of the two lists.

 ```i54 : table({1,2,3},{7,8},(i,j) -> 1000*i+j) o54 = {{1007, 1008}, {2007, 2008}, {3007, 3008}} o54 : List```

The function pack(L, n) turns the list L into a nested list, whose elements are lists containing the elements of L taken n at a time.

 ```i55 : pack(1..15, 4) o55 = {{1, 2, 3, 4}, {5, 6, 7, 8}, {9, 10, 11, 12}, {13, 14, 15}} o55 : List```

On the other hand, mingle(L) takes the nested list L = {L1, L2, ..., Ln} and combines the elements of the Li into a single list in the following way:

 ```i56 : mingle({{1,2,3,4}, {10,20,30,40}, {100,200,300,400}, {a, b}}) o56 = {1, 10, 100, a, 2, 20, 200, b, 3, 30, 300, 4, 40, 400} o56 : List```

Manipulating lists and sequences.

Use append(L, x) to create a copy of L with the element x added to the end. Since lists are immutable in Macaulay2, L itself is not changed, unless redefined.

 ```i57 : L = {926, 621, 429, 67, 594, 904, 264, 18, 35, 961};``` ```i58 : append(L, -10) o58 = {926, 621, 429, 67, 594, 904, 264, 18, 35, 961, -10} o58 : List``` ```i59 : L o59 = {926, 621, 429, 67, 594, 904, 264, 18, 35, 961} o59 : List``` ```i60 : L = append(L, -10); L o61 = {926, 621, 429, 67, 594, 904, 264, 18, 35, 961, -10} o61 : List```

Use prepend(x, L) to create a copy of L with x added to the beginning of the list. Notice the order of arguments is the opposite of append!

 ```i62 : L = prepend(-20, L) o62 = {-20, 926, 621, 429, 67, 594, 904, 264, 18, 35, 961, -10} o62 : List```

Use insert(n, x, L) to specify that the element x should be added to the list L at position n.

 ```i63 : L = insert(5, -30, L) o63 = {-20, 926, 621, 429, 67, -30, 594, 904, 264, 18, 35, 961, -10} o63 : List```

Use switch(m, n, L) to switch the elements of L in indices m and n.

 ```i64 : L = switch(1, 2, L) o64 = {-20, 621, 926, 429, 67, -30, 594, 904, 264, 18, 35, 961, -10} o64 : List```

The function delete removes elements that have a particular value, NOT a particular index.

 ```i65 : L = delete(-10, L) o65 = {-20, 621, 926, 429, 67, -30, 594, 904, 264, 18, 35, 961} o65 : List```

To remove the element at index n, use the command drop(L, {n,n}).

 ```i66 : L = drop(L, {1,1}) o66 = {-20, 926, 429, 67, -30, 594, 904, 264, 18, 35, 961} o66 : List```

You can also use drop to remove a specified number of elements from the beginning or end of L.

 ```i67 : L = drop(L, 2) o67 = {429, 67, -30, 594, 904, 264, 18, 35, 961} o67 : List``` ```i68 : L = drop(L, -2) o68 = {429, 67, -30, 594, 904, 264, 18} o68 : List```

On the other hand, use take to specify the number of elements to keep, or a range of indices to keep:

 ```i69 : L = take(L, 6) o69 = {429, 67, -30, 594, 904, 264} o69 : List``` ```i70 : L = take(L, {1,4}) o70 = {67, -30, 594, 904} o70 : List```

Use between(x, L) to insert the element x between every two elements of L.

 ```i71 : L = between(-5, L) o71 = {67, -5, -30, -5, 594, -5, 904} o71 : List```

Useful commands for reordering lists are reverse (reverse the current order), sort (put elements in ascending order), and rsort (put elements in descending order).

 ```i72 : L o72 = {67, -5, -30, -5, 594, -5, 904} o72 : List``` ```i73 : reverse L o73 = {904, -5, 594, -5, -30, -5, 67} o73 : List``` ```i74 : sort L o74 = {-30, -5, -5, -5, 67, 594, 904} o74 : List``` ```i75 : rsort L o75 = {904, 594, 67, -5, -5, -5, -30} o75 : List```

Use unique to remove duplicates from a list or sequence.

 ```i76 : unique L o76 = {67, -5, -30, 594, 904} o76 : List```

Use join to concatenate two lists or sequences. The symbol | is also used for concatenation.

 ```i77 : join(a..f, 1..6) o77 = (a, b, c, d, e, f, 1, 2, 3, 4, 5, 6) o77 : Sequence``` ```i78 : x_1..x_3 | y_1..y_4 o78 = (x , x , x , y , y , y , y ) 1 2 3 1 2 3 4 o78 : Sequence```

Mapping over lists.

In programming, loops that operate on consecutive elements of a list are common, so we offer various ways to apply functions to each of the elements of a list, along with various ways to treat the returned values.

The most basic operation is provided by scan, which applies a function consecutively to each element of a list, discarding the values returned.

 ```i79 : scan({a,b,c}, print) a b c```

The keyword break can be used to terminate the scan prematurely, and optionally to specify a return value for the expression. Here we use it to locate the first even number in a list.

 ```i80 : scan({3,5,7,11,44,55,77}, i -> if even i then break i) o80 = 44```

The function apply is similar to scan, but creates a list storing the values returned.

 ```i81 : apply({1,2,3,4}, i -> i^2) o81 = {1, 4, 9, 16} o81 : List```

This operation is so common that we offer two shorthand notations for it, one with the function on the right and one with the function on the left.

 ```i82 : {1,2,3,4} / (i -> i^2) o82 = {1, 4, 9, 16} o82 : List``` ```i83 : (i -> i^2) \ {1,2,3,4} o83 = {1, 4, 9, 16} o83 : List```

The associativity of these operators during parsing is set up so the following code works as one would wish.

 ```i84 : {1,2,3,4} / (i -> i^2) / (j -> 1000*j) o84 = {1000, 4000, 9000, 16000} o84 : List``` ```i85 : (j -> 1000*j) \ (i -> i^2) \ {1,2,3,4} o85 = {1000, 4000, 9000, 16000} o85 : List``` ```i86 : (j -> 1000*j) @@ (i -> i^2) \ {1,2,3,4} o86 = {1000, 4000, 9000, 16000} o86 : List```

The function apply can also be used with two lists of the same length, in which case it will apply the function consecutively to corresponding elements of the two lists.

 ```i87 : apply({1,2,3}, {7,8,9}, (i,j) -> 1000*i+j) o87 = {1007, 2008, 3009} o87 : List```

The function applyTable can be used to apply a function to each element of a table.

 ```i88 : applyTable( {{1,2,3},{4,5}}, i -> i^2) o88 = {{1, 4, 9}, {16, 25}} o88 : List```

The functions fold and accumulate provide various ways to iteratively apply a function of two arguments to the elements of a list. One of the arguments is the next element from the list, and the other argument is the value returned by the previous application of the function. As an example, suppose we want to convert the list {7,3,5,4,2} of digits into the corresponding number 73542. The formula (((7*10+3)*10+5)*10+4)+2 is a fast way to do it that doesn’t involve computing high powers of 10 separately. We can do this with fold and the following code.

 ```i89 : fold((i,j) -> i*10+j, {7,3,5,4,2}) o89 = 73542```

Using accumulate returns all the intermediate values of this iterative calculation along with the final result.

 ```i90 : accumulate((i,j) -> i*10+j, {7,3,5,4,2}) o90 = {73, 735, 7354, 73542} o90 : List```

Conditional expressions; selecting elements matching a criterion.

Use select to select those elements from a list that satisfy some condition.

 ```i91 : select({12, 3, -10, 42, 7, 6, 53}, even) o91 = {12, -10, 42, 6} o91 : List``` ```i92 : select({12, 3, -10, 42, 7, 6, 53}, i -> i<0 or i>40) o92 = {-10, 42, 53} o92 : List```

An optional first argument of an integer n specifies to select no more than n matching elements.

 ```i93 : select(2, {12, 3, -10, 42, 7, 6, 53}, even) o93 = {12, -10} o93 : List```

Use positions to select the indices of elements satisfying the condition.

 ```i94 : positions({12, 3, -10, 42, 7, 6, 53}, i -> i<0 or i>40) o94 = {2, 3, 6} o94 : List```

The singular position returns only the first (or last, by specifying Reverse => true) matching index.

 ```i95 : position({12, 3, -10, 42, 7, 6, 53}, i -> i<0 or i>40) o95 = 2``` ```i96 : position({12, 3, -10, 42, 7, 6, 53}, i -> i<0 or i>40, Reverse => true) o96 = 6```

Use number to count how many elements satisfy the condition.

 ```i97 : number({12, 3, -10, 42, 7, 6, 53}, i -> i<0 or i>40) o97 = 3```

Use max and min to find the maximum or minimum of the list. The functions maxPosition and minPosition give the index of the maximum/minimum. Note that max and min work with many Macaulay2 types besides numbers, for instance elements of a polynomial ring with respect to a monomial order.

 `i98 : R = QQ[x,y,z, MonomialOrder => Lex];` ```i99 : max {x^2*y*z, x*y^3*z^2, x^3, y^3, z} 3 o99 = x o99 : R``` ```i100 : maxPosition {x^2*y*z, x*y^3*z^2, x^3, y^3, z} o100 = 2``` ```i101 : min {x^2*y*z, x*y^3*z^2, x^3, y^3, z} o101 = z o101 : R``` ```i102 : minPosition {x^2*y*z, x*y^3*z^2, x^3, y^3, z} o102 = 4```

We may use any to tell whether there is at least one element of a list satisfying a condition, and all to tell whether all elements satisfy it.

 ```i103 : any({3, 6, 7, 8}, even) o103 = true``` ```i104 : all({3, 6, 7, 8}, even) o104 = false```

• # BasicList -- length
• BasicList # ZZ -- get element from list
• BasicList #? ZZ -- check for element in list
• VisibleList _ ZZ -- get element from list
• VisibleList _ List -- get some entries of a list
• List | List -- join lists, sequences or arrays
• all(BasicList,Function) -- whether all elements of a list satisfy a specified condition
• any(BasicList,Function) -- whether any elements of a list satisfy a specified condition
• append -- append an element to a list
• apply(BasicList,Function) -- apply a function to each element of a list
• between -- insert something between elements of a list
• delete -- delete some elements of a list
• drop -- Drop some elements from a list or sequence.
• first -- first element of a list
• flatten -- flatten a list by unnesting lists
• fold -- apply a binary operator repeatedly
• insert -- copy a list, inserting an element
• join -- join lists and sequences
• last -- last element of a list
• mingle -- mingle elements of several lists
• pack -- pack elements of a list into several shorter lists
• position -- the first element of a list satisfying a condition
• positions -- which elements of a list satisfy a condition
• prepend -- add an element to the beginning of a list
• reverse -- reverse a list or sequence
• rsort -- sort a list or matrix in reverse order
• scan(BasicList,Function) -- apply a function to each element in a list or sequence
• select -- select from a list, hash table, or string
• sort -- sort a list or columns of a matrix
• switch -- copy a list, switching two elements
• table -- make a table from a binary function
• take -- Take some elements from a list or sequence.
• unique -- eliminate duplicates from a list
• sequence -- make a sequence
• toList -- create a list
• toSequence -- convert to sequence
• unsequence -- extract the single element from a sequence of length 1