Tcl 列表
最后修改于 2023 年 10 月 18 日
在本 Tcl 教程中,我们将讨论列表。
计算机程序使用数据。处理数据组是基本的编程操作。在 Tcl 中,列表 是一种基本的数据结构。它是一个有序的值项集合。列表中的项由空格分隔。
列表的每个项都由其索引标识。列表没有固定长度。列表元素可以是字符串、数字、变量、文件或其他列表。我们可以将列表嵌套到其他列表中,深度不限。
创建列表
我们在 Tcl 中创建列表有几种方法。
#!/usr/bin/tclsh set l1 { 1 2 3 } set l2 [list one two three] set l3 [split "1.2.3.4" .] puts $l1 puts $l2 puts $l3
创建了三个列表,并将它们的元素打印到控制台。
set l1 { 1 2 3 }
创建列表的基本方法是将列表的元素放在花括号内。列表元素用空格分隔。
set l2 [list one two three]
创建列表的另一种方法是使用 list
命令。
set l3 [split "1.2.3.4" .]
一些 Tcl 命令会返回一个列表作为结果。在上面的代码行中,split
命令返回一个由字符串生成的数字列表。
$ ./createlists.tcl 1 2 3 one two three 1 2 3 4
llength 命令
llength
命令计算列表中元素的数量。
#!/usr/bin/tclsh puts [llength { 1 2 3 4 }] puts [llength {}] puts [llength { 1 2 {3 4} }] puts [llength { 1 2 {} 3 4 }]
脚本计算了四个列表的长度。
puts [llength { 1 2 3 4 }]
此列表有四个元素,因此将 4 打印到控制台。
puts [llength {}]
此列表为空;llength
命令返回 0。
puts [llength { 1 2 {3 4} }]
此列表包含一个内部列表 — {3 4}。内部列表算作一个元素。
puts [llength { 1 2 {} 3 4 }]
一个空列表也算作一个元素。
$ ./list_length.tcl 4 0 3 5
检索元素
有三个用于列表元素检索的基本命令:lindex
、lrange
和 lassign
。
#!/usr/bin/tclsh set vals { 2 4 6 8 10 12 14 } puts [lindex $vals 0] puts [lindex $vals 3] puts [lindex $vals end] puts [lindex $vals end-2]
代码示例使用 lindex
命令从列表中检索指定索引处的元素。
puts [lindex $vals 0] puts [lindex $vals 3]
Tcl 列表索引从 0 开始。上面的命令打印列表中位于位置 1 和 4 的元素。
puts [lindex $vals end] puts [lindex $vals end-2]
字符串 end
表示最后一个元素的索引。也可以从中减去一个整数。
$ ./retrieving.tcl 2 8 14 10
下一个代码示例解释了 lrange
和 lassign
命令。
#!/usr/bin/tclsh puts [lrange { a b c d e } 2 4] puts [lrange { a b c d e } 1 end] lassign { a b c } x y z puts "$x $y $z"
lrange
命令返回由两个索引指定的列表的一部分。lassign
命令将列表中的值分配给指定的变量。
puts [lrange { a b c d e } 2 4] puts [lrange { a b c d e } 1 end]
在这里,我们打印列表的两个子列表。
lassign { a b c } x y z puts "$x $y $z"
使用 lassign
命令,我们将列表元素分配给三个变量。
$ ./retrieving2.tcl c d e b c d e a b c
遍历列表
现在我们已经定义了列表和基本的列表操作,我们希望遍历列表元素。我们展示了几种遍历列表项的方法。
#!/usr/bin/tclsh foreach item {1 2 3 4 5 6 7 8 9} { puts $item }
我们使用 foreach
命令遍历列表元素。在每个循环周期中,item
变量都具有来自数字列表的下一个值。
$ ./traverse1.tcl 1 2 3 4 5 6 7 8 9
示例的输出。
在第二个示例中,我们使用 while
循环遍历星期几的名称。
#!/usr/bin/tclsh set days [list Monday Tuesday Wednesday Thursday \ Friday Saturday Sunday] set n [llength $days] set i 0 while {$i < $n} { puts [lindex $days $i] incr i }
我们使用 while
循环遍历列表。当使用 while
循环时,我们还需要一个计数器和列表中项目的数量。
set days [list Monday Tuesday Wednesday Thursday \ Friday Saturday Sunday]
使用 list
命令创建日期列表。
set n [llength $days]
使用 llength
命令确定列表的长度。
set i 0
这是一个计数器。
while {$i < $n} { puts [lindex $days $i] incr i }
while
循环执行主体中的命令,直到计数器等于列表中元素的数量。
puts [lindex $days $i]
lindex
从计数器指向的列表中返回一个值。
incr i
计数器递增。
$ ./traverse2.tcl Monday Tuesday Wednesday Thursday Friday Saturday Sunday
lmap 命令
可以使用 lmap
命令遍历列表的元素。它是一个函数式命令。lmap
命令遍历一个或多个列表中的所有元素并收集结果。
#!/usr/bin/tclsh set vals { 1 2 3 4 5 6 } puts [lmap a $vals {expr {$a ** 2}}]
该示例将 lmap
应用于一个整数列表。
puts [lmap a $vals {expr {$a ** 2}}]
函数式 lmap
命令将其主体中的表达式应用于 vals
列表的每个元素。返回结果,其中包含一个由平方整数组成的新列表。
$ ./lmap_cmd.tcl 1 4 9 16 25 36
插入元素
下一个示例将元素插入到 Tcl 列表中。lappend
命令将一个元素附加到列表的末尾;它修改了原始列表。linsert
命令将一个元素插入到指定的索引处;它不会修改原始列表,但会返回一个新列表。
#!/usr/bin/tclsh set nums {4 5 6} puts $nums lappend nums 7 8 9 puts $nums puts [linsert $nums 0 1 2 3] puts $nums
我们有一个包含三个数字的列表。
lappend nums 7 8 9
lappend
将数据附加到列表中。原始列表已更改。
puts [linsert $nums 0 1 2 3]
linsert
将元素插入到给定的索引处。第一个数字是索引。其余的值是要插入到列表中的数字。该命令创建一个新列表并返回它;它不会修改原始列表。
$ ./inserting.tcl 4 5 6 4 5 6 7 8 9 1 2 3 4 5 6 7 8 9 4 5 6 7 8 9
在下面的示例中,我们连接列表,搜索项目并替换列表中的项目。
#!/usr/bin/tclsh set animals1 { lion eagle elephant dog cat } set animals2 { giraffe tiger horse dolphin } set animals [concat $animals1 $animals2] puts $animals puts [lsearch -exact $animals eagle] puts [lreplace $animals 3 4 buffalo crocodile]
我们定义了两个动物列表。我们介绍了三个新命令。
set animals [concat $animals1 $animals2]
concat
命令用于连接(添加)两个列表。上面的行将两个列表连接起来,并将新列表设置为 animals 变量。
puts [lsearch -exact $animals eagle]
使用 lsearch
命令,我们在列表中查找鹰。使用 -exact
选项,我们查找完全匹配。该命令返回第一个匹配元素的索引,如果没有匹配项,则返回 -1。
puts [lreplace $animals 3 4 buffalo crocodile]
lreplace
命令将 dog 和 cat 替换为 buffalo 和 crocodile。
$ ./operations2.tcl lion eagle elephant dog cat giraffe tiger horse dolphin 1 lion eagle elephant buffalo crocodile giraffe tiger horse dolphin
排序项目
在本节中,我们将展示如何在 Tcl 列表中对项目进行排序。
#!/usr/bin/tclsh set names { John Mary Lenka Veronika Julia Robert } set nums { 1 5 4 3 6 7 9 2 11 0 8 2 3 } puts [lsort $names] puts [lsort -ascii $names] puts [lsort -ascii -decreasing $names] puts [lsort -integer -increasing $nums] puts [lsort -integer -decreasing $nums] puts [lsort -integer -unique $nums]
要对列表元素进行排序,我们可以使用 sort
命令。该命令不会修改原始列表。它返回一个新的排序后的元素列表。
set names { John Mary Lenka Veronika Julia Robert } set nums { 1 5 4 3 6 7 9 2 11 0 8 2 3 }
我们有两个列表。第一个包含字符串,第二个包含数字。
puts [lsort $names] puts [lsort -ascii $names]
默认排序是 ASCII 排序。元素按其在 ASCII 表中的位置排序。
puts [lsort -integer -increasing $nums] puts [lsort -integer -decreasing $nums]
我们将这些值视为整数,并按递增和递减顺序对它们进行排序。
puts [lsort -integer -unique $nums]
我们按数值顺序对列表的元素进行排序,按递增顺序。将删除重复项。
$ ./sorting.tcl John Julia Lenka Mary Robert Veronika John Julia Lenka Mary Robert Veronika Veronika Robert Mary Lenka Julia John 0 1 2 2 3 3 4 5 6 7 8 9 11 11 9 8 7 6 5 4 3 3 2 2 1 0 0 1 2 3 4 5 6 7 8 9 11
嵌套列表
在 Tcl 中,可以有嵌套列表 — 其他列表中的列表。
#!/usr/bin/tclsh set nums {1 2 {1 2 3 4} {{1 2} {3 4}} 3 4} puts [llength $nums] puts [llength [lindex $nums 2]] puts [lindex $nums 0] puts [lindex [lindex $nums 2] 1] puts [lindex [lindex [lindex $nums 3] 1] 1]
这是一个 Tcl 中嵌套列表的简单示例。
set nums {1 2 {1 2 3 4} {{1 2} {3 4}} 3 4}
nums
是一个包含两个嵌套列表的列表。第二个嵌套列表还有两个额外的内部嵌套列表。
puts [llength $nums]
我们确定列表的大小。嵌套列表算作一个元素。
puts [llength [lindex $nums 2]]
在本行中,我们确定第一个嵌套列表的大小,它是主列表的第三个元素。
puts [lindex $nums 0]
在这里,我们打印主列表的第一个元素。
puts [lindex [lindex $nums 2] 1]
在上面的行中,我们获取第一个嵌套列表的第二个元素。
puts [lindex [lindex [lindex $nums 3] 1] 1]
在这里,我们获取位于主列表的第 4 个位置的内部列表的第二个内部列表的第二个元素。换句话说:最里面的命令首先执行。[lindex $nums 3]
返回 {{1 2} {3 4}}
。现在,第二个命令对这个返回的列表进行操作。[lindex {{1 2} {3 4}} 1]
表达式返回 {3 4}
。最后,最后一个命令 [lindex {3 4} 1]
返回 4,打印到终端。
$ ./nestedlists.tcl 6 4 1 2 4
可以使用更简单的语法来检索嵌套列表的元素。
#!/usr/bin/tclsh set nums { 1 2 {1 2 3 {4 5}} 3 4 } puts [lindex $nums 0] puts [lindex $nums 2 1] puts [lindex $nums 2 3 1]
索引遵循 lindex
命令的第一个参数,从最外层列表的索引开始。
$ ./nestedlists2.tcl 1 2 5
在本 Tcl 教程中,我们介绍了 Tcl 列表。