IMSE Chapter 5

IMSE-05(Lists-Arrays).nb
Lists and Arrays in Mathematica
RCH 7/01
revised 6/11/02 - rjerwin

Mathematica uses collections of data called lists and arrays for a wide variety of operations.  To understand what Mathematica is doing in many calculations and to be able to control what is happening, you need a thorough understanding of lists and arrays and how to manipulate them.

In Mathematica a list is any collection of data that do not necessarily have to be of the same type.  You can have lists that are all numbers, lists that are all strings (letters, names, etc.), lists that are algebraic formulas, lists of graphs, and lists that combine various types of data.  You can even have lists that are made up of lists.

Lists

The simplest form of a list is just a collection of data surrounded by curly brackets {} with each item in the list separated by a comma.  In fact, as we shall see, when you ask Mathematica to display a list for you, it usually responds with this curly bracket form.  The following command assigns a list of numbers to the name myList.  When you activate the command, Mathematica just gives the list back to you again.

myList = {1, 3, 17, 2, -5}

You are not required to associate a name with the list, but it is helpful to have a name so you can easily refer to the list as a whole without having to retype all the elements of the list.  I prefer to use "List" as part of the name to remind me that in fact the name refers to a list. 

Let's see why using lists might be useful.  As a simple example, activate the following command.

5*myList

You see that Mathematica multiplies each number in the list by 5.  There are many operations of this sort that act on each element in the list.  In Mathematica-ese these operations are said to be "Listable," a strange but common usage.

You can extract individual elements from a list by using double brackets.  Let's pull out the fourth number in myList, 2.

myList[[4]]

Let's define a second list:

myList2 = {4, 5, 1, 0.5, - .4}

Now try the following commands.  Make sure you understand what is happening.

myList - myList2

myList + myList2

1/myList

As mentioned previously, you can also have lists that have mixed forms of data.  Let's create such a list.  Then try out the set of commands given in the subsequent input cells to see what happens.  The following list contains numbers, symbols, and a string.

mixedList = {4, 5, a, "Hello", (b^2)}

2*mixedList

mixedList2 = {2, 4, b, "Goodbye", Sin[b]}

mixedList + mixedList2

mixedList*mixedList2

1/mixedList

In the last line, Mathematica doesn't know what to do with 1/Hello so it simply returns your command.

In most science and engineering applications, lists will often be lists of numbers that we have computed or lists of numerical data from an experiment.  We will focus our attention on lists of numbers.

Mathematica has some nice features that allow you to fill in lists of numbers automatically.  These are useful in many situations.  For example, the following command generates a list of numbers from 3 to 21 in steps of 3.

numList1 = Range[3, 21, 3]

The set of three numbers in the argument of Range[] is called an "iterator" because it tells Mathematica to iterate (repeat) an operation over a certain range of values.

Often it is important to determine the "Length" of a list -- that is, how many elements are contained in the list.  The Mathematica command Length[listname] gives us that result.  Here is an example:

Length[numList1]

A somewhat more flexible command called Table[] can generate more complicated lists.  For example, the following command generates a table of values of Sin[k] with k running from 1 to 20 in steps of 2.  Here the iterator itself is a list surrounded by curly brackets.

numList2  = Table[Sin[k], {k, 1. , 20. , 2}]

What happens if you make the iterator {k,1,20,2}?  Try it.

Aside: you can get Mathematica to display the list in a column form by using the following command:

ColumnForm[numList1]
ColumnForm[numList2]

You can also define your own function which Mathematica will evaluate to fill in the table.  For example, the following cell generates a table of the values of 2 (x^2) + 3 (x^3) for x = 1 to 20.

h[x_] = 2*x^2 + 3*x^3
numList3 = Table[h[k], {k, 1, 20}]

N.B.  Some Mathematica users type the function directly inside the Table[] command square brackets.  For simple functions, that's perfectly ok.  But for more complicated functions, I find it much better to define the function separately as shown in the previous input cell.  That code is both easier to read and easier to modify.

Arrays

You can use the command called Array[] to generate the list.  The syntax is almost the same as that for Table[].  However, Array[] assumes that the argument goes from 1 to the value given in curly brackets in steps of 1.  With Table[], you can change the initial and final values as well as the step size.  The command Array[] is most often used for generating multi-dimensional lists as discussed below.  The following command uses the function h[x] previously defined to set up a list of 20 numerical values.

Array[h, {20}]

In many science and engineering applications, we want to generate a list of numbers as part of a calculation and there may not be a simple formula available.  How do we handle that situation in Mathematica?  The easiest way is to use the command Array[] to construct an empty list that we fill in as part of the calculation.  The following command produces a list (note the curly brackets in the Out[]= statement) consisting of elements d[1] .. d[15].  Note that the elements of the list are, at this stage, just the names d[1], etc.   We don't yet have a list with a name.

Array[d, 15]

Let's assign a name to the list.

dList = Array[d, 15]

You can also construct two-dimensional arrays as illustrated in the following comand.  Note the curly bracket list that serves as an iterator for generating the range of row and column indices.  If there is only one element in the iterator, as in the previous Array command, the curly brackets can be omitted.

gList = Array[g, {4, 2}]

If you are into multi-dimensional spaces, you can build arrays of however many dimensions you want, simply by including more arguments in the iterator.  For most of our purposes, two-dimensional arrays will suffice.

For ease of seeing what is going on with a two-dimensional array, you can have Mathematica display the array in a more standard mathematics form.  Here are two examples:

MatrixForm[gList]  
TableForm[
      gList]

MatrixForm[g]
TableForm[g]

Note that the results of the last series of commands tells us something about how Mathematica handles arrays.  The list gList consists elements g[1,1], g[1,2], etc.  Mathematica does not recognize "g" as the name of the list.  At this stage g[1,1] is just a symbol.  We'll explore this difference shortly.

Let's now see how to fill these arrays with some numbers.  First, let's use the following commands to assign specific numbers to g[1,1] and g[4,2].  The third command displays the array in TableForm.

g[1, 1] = 2.3;
g[4, 2] = -7.8;
TableForm[gList]

In the following, we will use Do loops to cycle through the elements of the array.  If you are not familiar with Do loops, just try out the commands to see the results.  You can learn about Do loops and other programming techniques in IMSE-09.

Note that the loop uses two iterators: one to cycle through the row numbers (1-4) and the other to cycle through the column numbers (1-2).

Do[g[j, k] = j*k^2, {j, 1, 4}, {k, 1, 2}]
TableForm[gList]

Of course, we could have used Table[] to generate this list since it involves a simple function.  But the procedure illustrates how you assign values to each of the elements of the array.  In more complicated calculations, you may be evaluating integrals, solving differential equations, etc., to compute values for the array.

We now want to see how to access the elements of the array individually.  You can do this two ways.  One is through the symbols g[1,1] etc.  The other is through the array name gList.  Note that for the g[3,1] form, we use only single brackets.  For the gList form, we need double square brackets.  The difference occurs because, as we mentioned above, Mathematica does not treat g[1,1], etc., as a list.  They are just names of the elements of a list, a subtle but important distinction.  gList is a Mathematica list and to access individual elements of a list, you need to use the double bracket notation.

g[3, 1]

gList[[3, 1]]

g[1, 1]

a = 3
b = 2
g[a, b]
gList[[a, b]]

Which form should you use?  For some purposes it doesn't matter.  On the other hand, if you want to multiply each element in the array by 5, then it is easiest to use the double bracket form.  My recommendation is to use the double bracket form most of the time because it gives you the greatest flexibility.

Exercise:  In the cell below, see what happens if you try to access gList[1,2].

Some additional features of lists and arrays.

Mathematica has some nice features that use lists.  For example, if you have a two-dimensional array of numbers in a list, you can use ListPlot[] to generate a graph of the second column (the ordinate or dependent variable) as a function of the first column (the abcissa or independent variable.)

sineList = Array[k, {10, 2}]; (*This command sets up the list .   Note that ListPlot[] assumes the structure {{x1, y1}, {x2, y2},  ... }.*)
Do[k[i, 1] = i; 
      k[i, 2] = i*Sin[i], {i, 1, 10}]
ListPlot[
        sineList];

Of course, the previous example could have been done simply with the Plot[] command.  ListPlot[] gives you more flexiblity in plotting data either from complicated calculations or from data imported from other programs.  (Importing and Exporting data is treated in IMSE-11.)

We can also use Table[] to build a list of repeated operations.

Table[{x, x^2, x^3}, {x, 2, 23}] // TableForm

We can also construct arrays the other way around.  First, fill in the array, then assign it to a list.  Note that we need to use Clear[a].  Otherwise, Mathematica remembers the previous definition a = 3 and then tries to figure out what you mean by 3[1,1], 3[1,2], etc.

Clear[
        a];
  
Do[a[k, 1] = k/10; 
      a[k, 2] = k^3, {k, 1, 6}]

      
myList2 = 
        Array[a, {6, 
            2}];
  
ListPlot[myList2];

Combining Lists

Sometimes it is useful to be able to combine two one-dimensional lists to form a single two-dimensional list to use with ListPlot[].  Or, you may want to combine several lists to generate one big list for exporting data to other programs.  The command Transpose[] does this job for you.  (Transpose[] can also be used to interchange the rows and columns of a single matrix.  Here, we are simply combining lists, though in essence we are still interchanging columns and rows.)  In the application below we go from two 1-column, 7-row matrices to a single 2-column, 7-row matrix.  The first element of the new list is itself a list (contained within curly brackets).  The first column of the combined matrix is the first list.

(*Combine two lists for ListPlot.*) 
t = {1, 2, 3, 4, 5, 6, 7};
v = {0, 4, 6, 8, 10, 12, 
          14};
  
dataplotList = Transpose[{t, v}] ;
Print["t = ", t // MatrixForm]
Print["v = ", v // MatrixForm]
Print["dataplotList = ", 
      dataplotList // MatrixForm]
ListPlot[dataplotList];

You can also combine lists by using the Table[] command.  The following cell uses the previously defined lists t and v to make a new list.  Note the use of the double brackets to access individual elements of the lists.

dataplotList2 = 
      Table[{t[[k]], v[[k]]}, {k, 1, 
          Length[t]}]
ListPlot[dataplotList2];

You can use the Table[] command to go directly from arrays to a combined list.  In the next cell, we use a Do loop to generate two arrays.  Table[] then combines the arrays into a two-dimensional list in order to plot (p^3)as a function of (p^2).

Do[f[p] = p^2; w[p] = p^3, {p, 1, 10}]
data3List = Table[{f[p], w[p]}, {p, 1, 10}]
ListPlot[data3List];

Taking Lists Apart

Sometimes you need to disassemble a list.  As an example, let's use Part[] to take apart the list dataplotList that we constructed above.  For example, to pull out the first "column" of dataplotList values, we use Part[dataplotList,All,1].  Activate the following cell to see how this works.

tList = Part[dataplotList, All,  1]
vList = Part[dataplotList,  All,  2]

For one-dimensional lists, you can use Drop and Take to get parts of lists.

tlessList = 
      Drop[tList, 
        2]  
vlessList = 
      Drop[vList, -2]  
Take[
      tList, {2, 
        4}] (*Takes elements 2 through 4 from tList.*)

Concluding Comments

Mathematica has many commands for working with lists.  For example, there are commands that allow you to append new data to exisiting lists, break up an existing list in various ways, access individual members of a list, "flatten" a list, reconstruct a list consisting of sublists into a single long list of elements, and so on.  Mathematica Help provides a good starting point for exploring these options.