如何将列表的某些部分复制到TCL中的新列表?

时间:2013-10-02 13:38:23

标签: list copy tcl

我有一个列表如下:

set list1 {1,2,3,4,5,6,7,8,9}

每次如何将它的三个元素复制到另一个列表?

例如复制后:

listc1 is {1,2,3}
listc2 is {4,5,6}
listc3 is {7,8,9}

3 个答案:

答案 0 :(得分:5)

您的第一个语句略有偏离:Tcl不使用逗号分隔列表元素,它使用空格。下面是一个代码片段,可以执行您想要的操作:

set list1 {1 2 3 4 5 6 7 8 9}
set counter 0
foreach {a b c} $list1 {
    set listc[incr counter] [list $a $b $c]
}

讨论

  • foreach语句一次从列表中获取3个元素。在第一次迭代中,a = 1,b = 2,c = 3。在第二个中,a = 4,b = 5,c = 6,依此类推。
  • 表达式listc[incr counter]将产生listc1listc2,...
  • 如果列表的长度不能被3整除,则最后listc*将填充空元素。

答案 1 :(得分:1)

这是一种方法,应该适用于任何版本的Tcl

proc partition {lst size} {
    set partitions [list]
    while {[llength $lst] != 0} {
        lappend partitions [lrange $lst 0 [expr {$size - 1}]]
        set lst [lrange $lst $size end]
    }
    return $partitions
}

set list1 {1 2 3 4 5 6 7 8 9}
lassign [partition $list1 3] listc1 listc2 listc3

foreach var {listc1 listc2 listc3} {puts $var=[set $var]}
listc1=1 2 3
listc2=4 5 6
listc3=7 8 9

在Tcl 8.6中,我将研究如何使用协程并生成下一个分区。


概括@kostik的回答:

proc partition {list size} {
    for {set i 0; set j [expr {$size - 1}]} {$i < [llength $list]} {incr i $size; incr j $size} {
        lappend partitions [lrange $list $i $j]
    }
    return $partitions
}

答案 2 :(得分:1)

set list1 {1 2 3 4 5 6 7 8 9}
set listc1 [lrange $list1 0 2]
set listc2 [lrange $list1 3 5]
set listc3 [lrange $list1 6 9]

从Tcl 8.4开始,最后一条语句可能写成

set listc3 [lrange $list1 6 end]