Next: , Previous: Fundamental containers, Up: Basic concepts

### 4.9 Lists of expressions

The GiNaC class `lst` serves for holding a list of arbitrary expressions. They are not as ubiquitous as in many other computer algebra packages, but are sometimes used to supply a variable number of arguments of the same type to GiNaC methods such as `subs()` and some `matrix` constructors, so you should have a basic understanding of them.

Lists can be constructed by assigning a comma-separated sequence of expressions:

```     {
symbol x("x"), y("y");
lst l;
l = x, 2, y, x+y;
// now, l is a list holding the expressions 'x', '2', 'y', and 'x+y',
// in that order
...
```

There are also constructors that allow direct creation of lists of up to 16 expressions, which is often more convenient but slightly less efficient:

```         ...
// This produces the same list 'l' as above:
// lst l(x, 2, y, x+y);
// lst l = lst(x, 2, y, x+y);
...
```

Use the `nops()` method to determine the size (number of expressions) of a list and the `op()` method or the `[]` operator to access individual elements:

```         ...
cout << l.nops() << endl;                // prints '4'
cout << l.op(2) << " " << l[0] << endl;  // prints 'y x'
...
```

As with the standard `list<T>` container, accessing random elements of a `lst` is generally an operation of order O(N). Faster read-only sequential access to the elements of a list is possible with the iterator types provided by the `lst` class:

```     typedef ... lst::const_iterator;
typedef ... lst::const_reverse_iterator;
lst::const_iterator lst::begin() const;
lst::const_iterator lst::end() const;
lst::const_reverse_iterator lst::rbegin() const;
lst::const_reverse_iterator lst::rend() const;
```

For example, to print the elements of a list individually you can use:

```         ...
// O(N)
for (lst::const_iterator i = l.begin(); i != l.end(); ++i)
cout << *i << endl;
...
```

which is one order faster than

```         ...
// O(N^2)
for (size_t i = 0; i < l.nops(); ++i)
cout << l.op(i) << endl;
...
```

These iterators also allow you to use some of the algorithms provided by the C++ standard library:

```         ...
// print the elements of the list (requires #include <iterator>)
std::copy(l.begin(), l.end(), ostream_iterator<ex>(cout, "\n"));

// sum up the elements of the list (requires #include <numeric>)
ex sum = std::accumulate(l.begin(), l.end(), ex(0));
cout << sum << endl;  // prints '2+2*x+2*y'
...
```

`lst` is one of the few GiNaC classes that allow in-place modifications (the only other one is `matrix`). You can modify single elements:

```         ...
l[1] = 42;       // l is now {x, 42, y, x+y}
l.let_op(1) = 7; // l is now {x, 7, y, x+y}
...
```

You can append or prepend an expression to a list with the `append()` and `prepend()` methods:

```         ...
l.append(4*x);   // l is now {x, 7, y, x+y, 4*x}
l.prepend(0);    // l is now {0, x, 7, y, x+y, 4*x}
...
```

You can remove the first or last element of a list with `remove_first()` and `remove_last()`:

```         ...
l.remove_first();   // l is now {x, 7, y, x+y, 4*x}
l.remove_last();    // l is now {x, 7, y, x+y}
...
```

You can remove all the elements of a list with `remove_all()`:

```         ...
l.remove_all();     // l is now empty
...
```

You can bring the elements of a list into a canonical order with `sort()`:

```         ...
lst l1, l2;
l1 = x, 2, y, x+y;
l2 = 2, x+y, x, y;
l1.sort();
l2.sort();
// l1 and l2 are now equal
...
```

Finally, you can remove all but the first element of consecutive groups of elements with `unique()`:

```         ...
lst l3;
l3 = x, 2, 2, 2, y, x+y, y+x;
l3.unique();        // l3 is now {x, 2, y, x+y}
}
```