Skip to content
VLSI Mentor

Tcl Part I · Module 6 · Lists

lrange: Taking a Slice

Where lindex gives you one element, this gives you a run of them as a new list. It follows the same index rules, so there is little new mechanism to learn, and it turns two common jobs into one-liners: discarding a header row before processing a file, and keeping only the most recent few entries. The one thing worth slowing down for is a distinction that looks like a technicality and is not — a slice of one element is a list containing that element, which is not the same value as the element itself.

Foundation10 min readTclPart IListsSlicing

Part I · Module 6 · Chapter 6.5 · lrange

1. The Command

Azvya Education Pvt. Ltd.VLSI Mentor
basic.tcl
set lines {header r1 r2 r3 r4}

puts "1 to 3   -> [lrange $lines 1 3]"
puts "0 to end -> [lrange $lines 0 end]"
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
1 to 3   -> r1 r2 r3
0 to end -> header r1 r2 r3 r4

A first and a last position, both inclusive, returning a new list.

Inclusive on both ends is the same rule as string range — Chapter 5.3 §3 — and the same difference from languages with exclusive upper bounds. 1 3 is three elements, not two.

2. The Two Jobs You Will Use It For

Dropping a header row:

Azvya Education Pvt. Ltd.VLSI Mentor
drop-header.tcl
set lines {"name width" "clk 1" "reset 1" "payload 64"}

set body [lrange $lines 1 end]

puts "rows: [llength $body]"
foreach row $body {
    puts "  $row"
}
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
rows: 3
  clk 1
  reset 1
  payload 64

One line instead of a loop with a counter and a skip condition.

Keeping the last few:

Azvya Education Pvt. Ltd.VLSI Mentor
last-n.tcl
set history {run1 run2 run3 run4 run5}

puts "last 3: [lrange $history end-2 end]"
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
last 3: run3 run4 run5

end-2 end is the idiom for "the last three", exactly as in Chapter 5.3 §3.

3. Out of Range Is an Empty List

Azvya Education Pvt. Ltd.VLSI Mentor
out-of-range.tcl
set l {a b c}

puts "5 to 10 -> <[lrange $l 5 10]>"
puts "2 to 0  -> <[lrange $l 2 0]>"
puts "-5 to 1 -> <[lrange $l -5 1]>"
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
5 to 10 -> <>
2 to 0  -> <>
-5 to 1 -> <a b>

No errors. A range past the end is empty, a reversed range is empty, and a range starting before the list is clamped to the beginning.

Same behaviour as string range, and the same caution applies — an empty result from a miscalculated position looks exactly like an empty result from an empty input.

4. A Slice Is Not an Element

This is the distinction worth the chapter.

Azvya Education Pvt. Ltd.VLSI Mentor
slice-vs-element.tcl
set l {{two words} beta}

set slice   [lrange $l 0 0]
set element [lindex $l 0]

puts "slice:   <$slice>   llength [llength $slice]"
puts "element: <$element> llength [llength $element]"
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
slice:   <{two words}>   llength 1
element: <two words>     llength 2

lrange $l 0 0 gave a list containing one element. lindex $l 0 gave the element.

With a single-word element the two print identically and you never notice. With a multi-word element they are clearly different values, and passing one where the other was expected changes the element count downstream.

5. Index Arithmetic Works

Azvya Education Pvt. Ltd.VLSI Mentor
arithmetic.tcl
set l {a b c d e}
set i 2

puts "before i: [lrange $l 0 $i-1]"
puts "after i:  [lrange $l $i+1 end]"
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
before i: a b
after i:  d e

The same no-expr arithmetic as Chapter 6.4 §2. This is the shape for splitting a list at a found position.

6. It Returns a New List

Azvya Education Pvt. Ltd.VLSI Mentor
new-list.tcl
set l {a b c d}

lrange $l 1 2
puts "unchanged: $l"

set middle [lrange $l 1 2]
puts "stored:    $middle"
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
unchanged: a b c d
stored:    b c

Nothing is modified. To remove a span from a variable you want lreplace, which is the next chapter.

7. Taking a Page at a Time

A pattern worth seeing, since it combines what you have:

Azvya Education Pvt. Ltd.VLSI Mentor
paging.tcl
set items {a b c d e f g}
set page_size 3

set page 0
while {$page * $page_size < [llength $items]} {
    set first [expr {$page * $page_size}]
    set last  [expr {$first + $page_size - 1}]

    puts "page $page: [lrange $items $first $last]"
    incr page
}
Azvya Education Pvt. Ltd.VLSI Mentor
Snippet
page 0: a b c
page 1: d e f
page 2: g

The last page is short and needs no special handling, because a range running past the end is clamped rather than failing — §3 working in your favour.

while is Module 9; the point here is that lrange does the awkward part.

8. Common Mistakes

Expecting an exclusive end. Both ends are inclusive. §1.

Confusing a one-element slice with the element. §4.

Using positions from a search without checking. Chapter 6.3 §3.

Expecting it to modify the list. It returns a new one. §6.

Reaching for a loop to drop a header. §2.

9. Exercises

Exercise 1 — slices. From {a b c d e}, produce b c d, d e, the whole list, and an empty list, each with one lrange.

Exercise 2 — inclusive ends. How many elements does lrange $l 1 3 return? Predict, then confirm.

Exercise 3 — drop and keep. Given a six-line list, drop the first line and keep the last two, in two separate statements.

Exercise 4 — slice versus element. Build a list whose first element is two words. Print lrange $l 0 0 and lindex $l 0 with their lengths, and explain the difference.

Exercise 5 — out of range. Predict the result of lrange {a b c} 10 20 and lrange {a b c} 2 1. Then say why neither errors.

Exercise 6 — split at a position. With a five-element list and set i 2, produce the elements before i and after i without using expr.

10. Remember

  • lrange list first last returns a new list, with both ends inclusive.
  • end and end-N work, as does arithmetic like $i-1.
  • lrange $l 1 end drops a header; lrange $l end-2 end keeps the last three.
  • Out of range gives an empty list, a reversed range gives an empty list, and a range starting before the list is clamped.
  • A one-element slice is a list, not the element. lindex for a value, lrange for a list.
  • It returns a new list and never modifies the original.

Next: adding to a list.

Where this fits

Part of the Tcl curriculum.