linsert

linsert inserts elements into a list.

Synopsis

linsert list index element1 ?element2 element3 ...?

This returns a list that consists of list with the given elements inserted at index. It does not modify list itself.

Description

linsert returns a new list, leaving the original list unmodified. To "modify" a list:

set list [linsert $list 0 myvalue]

or, if the list is large make sure the list is unshared for linsert so that the internal Tcl_Obj can be re-used for the return value:

set list [linsert $list[set list {}] 0 myvalue]

The following proc makes it a little easier:

proc lipinsert {_list index args} {
    upvar $_list list
    set list [linsert [K $list [set list ""]] $index {*}$args]
}
> set A [list 1 2 3]
1 2 3
> lipinsert A 1 a b c
1 a b c 2 3

Prepend

DKF 2004-10-26: linsert can be used to create a lprepend command that is like lappend except that it puts the values at the start of the list:

proc lprepend {var args} {
    upvar 1 $var v
    lappend v ;# Used as a an "is a list" check and to do var creation
    set v [linsert $v[set v {}] 0 {*}$args]
}

Lars H: Has the above any advantage in comparison with

set v [linsert $v [set v 0] {*}$args]

which is anyway slightly shorter? (OK, it can be used also where there isn't another argument to place the set v <whatever> in, but what about those cases where an alternative exists? Is the idea of the example to establish a new idiom?)

PYK 2014-02-09: Lars H was spot-on back in 2004. A new idiom has indeed been established.

Append

linsert can be used to append elements to a list. In contrast with lappend, the list must already exist.

Unshared pure list

AMG: linsert always returns an unshared pure list. This fact may be helpful for performance measuring, as I recently showed on the Additional list functions page. Just give your list-to-be as the first argument, any valid index (e.g. 0) as the second, and no further arguments.

(I'm not sure if it's always, always pure, i.e. lacking in string representation, but it was when I tested it earlier today.)

Documentation Bug: end-relative index

This documentation bug , reported by amg, was fixed in 2010 .

AMG: According to the man page, "linsert produces a new list from list by inserting all of the element arguments just before the index’th element of list." When doing end-relative indexing, this definition doesn't match the actual behavior. To explain how index is interpreted, the linsert man page refers to the string index man page, which says that end indicates the last element. From this I expect that linsert {0 1 2} end x will return 0 1 x 2, the result of inserting x just before the end element of the list, which is 2. However, it actually returns {0 1 2 x}, so when doing end-relative indexing it inserts the new elements just after the indicated index. An alternative, more plausible explanation is that it inserts the new elements such that the first or last of the inserted elements will occupy the indicated index.

Please see my related comments on the lreplace page.

See also

list
contains links to all the other list commands