Lists and Keyed Lists

Lists

A list is an ordered collection of elements, of no fixed length. The list elements can be any string values, including numbers, variable names, file names, bits of Tcl code and other lists. The latter is possible because lists are just strings with a special interpretation that gives them structure. Lists may be nested to any depth, and are useful for representing trees, among other things.

List Representation

Lists are whitespace-separated strings. Braces and backslashes can be used to encapsulate whitespace in a list element and therefore to allow sublists. All lists are strings, but not all strings are lists.

Tcl Commands Have List Structure

List Constructors

Since lists are just strings with a certain structure, you can create lists simply by creating strings:
set L {a b c}
set L {1 {2 3} 4}
set L {string length phantasm}
You will often find it more convenient to use Tcl's list constructor commands, as they assure that your lists have proper list structure.

The list Command

The list command takes any number of arguments and returns a list of those arguments. The length of the returned list is the same as the number of arguments given to the list command. The arguments to list need not have proper list structure: they will be automatically quoted as necessary. This last is a very important feature of list.

If any of the arguments to list are themselves lists, the result will be a nested list structure.

The concat Command

The concat command also combines any number of arguments into a list. However, if any its arguments are lists, they are flattened into the result list. The result of concatis the concatenation of all the elements of the argument list into a single list.

concat only flattens one level of list:

llength [concat a b {c d} {e {1 2 3} f} g]
=> 8

The split Command

split makes a list from a string by splitting the string up into list elements.
split "keith:cdridjyhTp2FQ:100:1100:Keith Waclena:/home/keith:/host/bin/zsh" :
=> keith cdridjyhTp2FQ 100 1100 {Keith Waclena} /home/keith /host/bin/zsh
split abcde {}
=> a b c d e

List Selectors

The lindex Command

lindex returns an element of a list based on its position in the list; list elements are numbered from zero.

The lrange Command

lrange returns a contiguous range of a list, from one position to another. The first argument is a list. The second argument is the index of the first element of the range (zero-based). The third argument is the index of the last element of the range (so to select one element, the second index should be the same as the first). If the second index is the string end, the range extends to the end of the list.

List Modifiers

The linsert Command

linsert inserts new elements at a given position in a list.

The lreplace Command

lreplace changes a range of existing list elements by replacing them with new elements. The number of new elements needn't match the number of elements replaced. lreplace can also delete a range of elements.

The lrmdups Command

Extended Tcl. The lrmdups command removes repeated or duplicate items from a list. The resulting list will be sorted in lexicographic order.

List Predicates

The lempty Command

Extended Tcl. The lempty command returns 1 if its argument list is the empty list, or 0 otherwise. This is exactly equivalent to comparing the candidate list to the empty string for equality, but lempty reads better and is slightly simpler to write:
lempty $x
expr $x == ""

List Variables

A number of Tcl (and especially Extended Tcl) list commands use call-by-name to side-effect variables that contain lists. As usual, these commands are more efficient than doing the equivalent job with call-by-value.

The lappend Command

The lappend command appends elements to a list in a variable efficiently. It is exactly analogous to the append command.

The lassign Command

Extended Tcl. The lassign command does multiple assignment of the elements of a list to a corresponding set of variables. Any elements left over in the list (because not enough variables were provided) are returned as a list by lassign. For example:
lassign {1 2 3 4 5} a b c
=> 4 5
set a
=> 1
set b
=> 2
set c
=> 3

This is more efficient and much more readble than the equivalent series of set and lindex commands.

The lvarcat Command

Extended Tcl. lvarcat is a call-by-name version of concat. All arguments except the first are concat'ed together onto the end of the list stored in the variable named by the first argument.
set x [list x y]
=> x y
lvarcat x 1 2 {a b} 3
=> x y 1 2 {a b} 3
set x [list x y]
=> x y
set x [concat $x 1 2 {a b} 3]
=> x y 1 2 {a b} 3

The lvarpush and lvarpop Commands

Extended Tcl. lvarpush and lvarpop make it easy to use lists as stacks. lvarpush adds a new element to the beginning of the list stored in the named variable (the variable is created if necessary):
set x
Error: can't read "x": no such variable
lvarpush x 1
=> 
lvarpush x 2
=> 
lvarpush x 3
=> 
set x
=> 3 2 1
Note that lvarpush returns no value (or equivalently, it always returns the empty string as it's result).

lvarpop removes the first element from the list stored in the variable named by its argument, and returns that element as its result:

lvarpop x
=> 3
set x
=> 2 1
lvarpop x
=> 2
set x
=> 1
lvarpop x
=> 1
set x
=>

Stacks can be implemented with set, concat and lindex, but lvarpush and lvarpop are more readable and more efficient:

set x {}
=> 
set x [concat 1 $x]
=> 1
set x [concat 2 $x]
=> 2 1
set x [concat 3 $x]
=> 3 2 1
lindex $x 0
=> 3
set x [lreplace $x 0 0]
lindex $x 0
=> 2
set x [lreplace $x 0 0]
lindex $x 0
=> 1
set x [lreplace $x 0 0]
set x
=> 

Both lvarpush and lvarpop will manipulate other elements of the list than just the first, but I recommend avoiding these forms and using linsert and lreplace instead.

Other List Functions

The join Command

join is the inverse of split: it forms a string from a list by inserting a particular character between each list element. For example:
join [list 1 2 3] ,
=> 1,2,3
join [split "keith:cdridjyhTp2FQ:100:1100:Keith Waclena:/home/keith:/host/bin/zsh" :] :
=> keith:cdridjyhTp2FQ:100:1100:Keith Waclena:/home/keith:/host/bin/zsh

The llength Command

llength returns the length of a list (in elements). Compare to the length of the list as a string:
set x [list foo bar baz]
=> foo bar baz
llength $x
=> 3
string length $x
=> 11

The lsearch Command

lsearch searches a list for a particular element or elements. Any of the standard Tcl pattern matching options may be used to determine how the matching is done. The result is the index of the first matching element, or -1 if there were no matches.

The lmatch Command

Extended Tcl. lmatch is similar to lsearch, but it returns not the first matching element, but rather a list of all matching elements. Any of the standard Tcl pattern matching options may be used to determine how the matching is done.

The lsort Command

The lsort command takes a list as argument and returns the list, sorted, as its result. It takes many options indicating how to sort the list or compare elements.

The intersect Command

Extended Tcl. intersect treats two list arguments as sets and returns the set (list) which is their intersection:
intersect {a b c} {x y z}
=> 
intersect {a b c} {x a c}
=> a c
intersect {a b c} {x a a a c a}
=> a c

The intersect3 Command

Extended Tcl. intersect3 is similar to intersect, but returns a list of three results. Call the first argument to intersect3 A and the second B. Then the first of the three results is A - B, the second result is A intersect B, and the third reuslt is B - A. All three result lists are will be sorted.
intersect3 {a b c} {x a a a c a}
=> b {a c} x

The union Command

Extended Tcl. Returns the set theoretic union of its two arguments. Since we are treating lists as sets, duplicates are removed.

Problems With Tcl Lists

Efficiency

Ambiguity

Distinguishing A List of One Element from The Element Itself
A simple string like foo is indistinguishable from a list of length one containing the list element foo.
set x [list a [list b] c]
set y [list a b c]
set x
=> a b c
set y
=> a b c

Keyed Lists

Keyed lists are an Extended Tcl data structure that provides a facility for record structures (like struct in C; record in Pascal, structures in PL/I, etc).

Like lists, keyed lists are actually strings that obey a certain . A keyed list is a list of name, value pairs. Each pair is itself a list, so keyed lists are simply lists of pairs or lists of lists. Extended Tcl provides a number of commands to manipulate keyed lists efficiently; these commands use call-by-name to manipulate a keyed list stored in a variable.

The keylset Command

Extended Tcl. Sets a field in the keyed list to a particular value. Returns no value. Creates the variable if necessary.
keylset x NAME {Terry Dactyl}
set x
=> {NAME {Terry Dactyl}}
keylset x ADDRESS {1492 Columbus}
set x
=> {NAME {Terry Dactyl}} {ADDRESS {1492 Columbus}}
keylset x NAME {Jerry Atric}
set x
=> {NAME {Jerry Atric}} {ADDRESS {1492 Columbus}}

The keylget Command

Extended Tcl. Fetches the value associated with a particular field. Comes in two forms: a call-by-name form and a call-by-value form.
Call-by-value form
The call-by-value form returns the value of the field as its result; an error is signalled if the field isn't present.
keylget x NAME
=> Jerry Atric
keylget x DISPOSITION
=> Error: key "DISPOSITION" not found in keyed list
Call-by-name form
The call-by-name form stores the value of the field into a named variable and returns 1 to indicate success. If the requested field doesn't exist, 0 is returned. If the empty string is given as the name of the variable, the status code is returned but the variable isn't set.
keylget x NAME n
=> 1
set n
=> Jerry Atric
keylget x DISPOSITION
=> 0
keylget x ADDRESS {}
=> 1

The keylkeys Command

Extended Tcl. keylkeys returns a list of all field names that are defined in the keyed list.

The keyldel Command

Extended Tcl. Deletes the named field from the keyed list; both the field name and value are deleted.
Keith Waclena
The University of Chicago Library
This page last updated: Tue Aug 2 12:22:41 CDT 1994
This page was generated from Extended HTML by xhtml.