TIP 367: A Command to Remove Elements from a List

State:          Final
Type:           Project
Tcl-Version:    8.7
Vote:           Done
Author:         Donal K. Fellows <[email protected]>
Created:        18-May-2010
Keywords:       Tcl, delete, item
Tcl-Branch:     tip-367
Votes-For:      DKF, JN, DGP, FV, SL, AK
Votes-Against:  none
Votes-Present:  none 


This TIP proposes a command, lremove, that takes a list value and a collection of indices, and returns a list that is the input list with the elements at those indices removed.


Tcl has many operations for working with lists, such as list for building them, lappend for adding to them, linsert for insertion, lreplace for replacement of ranges, and lset for replacement of individual elements, but it has none that is designed to remove elements of a list. While the functionality can be simulated in the simple case with lreplace, this is rather more difficult when multiple indices are present. It is particularly challenging when using a mixture of indices that are defined relative to the start and the end of the list. Since the tools for doing the mapping of indices to list positions are easily available at the C level, I propose to add a command to Tcl to do the removal operation that takes advantage of the capabilities to do this all correctly.

Proposed Change

This TIP proposes adding a command, lremove, with the following syntax:

lremove list ?index? ?index...?

That is, the command takes one mandatory argument, list, and an arbitrary number of index arguments (including zero). The list argument must be a valid Tcl list, and each of the index arguments must be a valid Tcl index (see [176] for a description) where end will refer to the last element of list. Assuming syntactic validity, the result will be a list that is the same as list except for the removal of the elements at each given index. The result shall be as if all removals happen simultaneously and the order of the index arguments shall be unimportant; if an element is indicated twice (whether through syntactically identical indices or not) then it will be as if it was only indicated once.


% lremove {a b c d e} 1
a c d e
% lremove {a b c d e} end-1
a b c e
% lremove {a b c d e} 1 3
a c e
% lremove {a b c d e} 3 1
a c e
% lremove {a b c d e} 2 2
a b d e
% lremove {a b c d e} 3 end-1
a b c e
% lremove {a b c d e} 1 3 1 4 0


See the tip-367 branch.


The author of this TIP considers it highly acceptable to extend it to make each index be able to be an index list that addresses into a nested list (in the manner of lset) to find elements to delete, so long as the constraint remains that the indices can be provided in any order and it is not an error to have one index mask another.

He does not provide an implementation that supports this.


This document has been placed in the public domain.