2

我有一个如下列表:

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}
4

3 回答 3

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]将产生listc1, listc2, ...
  • 如果列表的长度不能被三整除,那么最后一个listc*将被空元素填充。
于 2013-10-02T14:01:23.023 回答
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
}
于 2013-10-02T13:59:24.563 回答
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]
于 2013-10-02T14:28:47.587 回答