Tcl:字符串列表的奇怪行为
Tcl: strange behavior of string list
在下面的代码中,我在 for
循环中生成一个字符串列表,如下所示:
set section 5;
set value 2;
set value_range_new "";
for { set i [expr -$section-1]} {$i <= $section} {incr i} {
if {$i < [expr -$section]} {
lappend value_range_new "\<[expr [expr $i+1]*$value]";
} elseif {$i == $section} {
lappend value_range_new "\>[expr $i*$value]";
} else {
lappend value_range_new "\[[expr $i*$value]\,[expr [expr $i +1]*$value]\)";
}
}
然后如果我puts
列表出来,结果如下:
<-10 {[-10,-8)} {[-8,-6)} {[-6,-4)} {[-4,-2)} {[-2,0)} {[0,2)} {[2,4)} {[4,6)} {[6,8)} {[8,10)} >10
令人困惑的一点是我不明白 {}
是从哪里来的。如果我像下面这样手动定义列表:
set a "\<-8 \[-8,-6\) \[-6,-4\) ";
看跌结果没有{}
。那么我的代码有什么问题,以及如何删除/
在 Tcl 中,您需要知道哪些命令要使用列表,哪些命令要使用字符串。 lappend
是一个列表命令。 puts
接受一个字符串。当您给 puts
一个列表时,Tcl 会将列表转换成它的字符串表示形式。这意味着您会看到一些额外的大括号和反斜杠,以保护具有特殊字符(如 [
和 ]
)的列表元素。
您可以使用 join
命令轻松地将列表转换为字符串。
对于构建字符串,format
命令可以提高可读性。
此外,您不需要接下来的expr
命令,使用括号;和 brace your expressions:
set section 5;
set value 2;
set value_range_new "";
for { set i [expr {-$section-1}]} {$i <= $section} {incr i} {
set this [expr {$i * $value}]
set next [expr {($i + 1) * $value}]
if {$i < -$section} {
lappend value_range_new [format {<%d} $next]
} elseif {$i == $section} {
lappend value_range_new [format {>%d} $this]
} else {
lappend value_range_new [format {[%d,%d)} $this $next]
}
}
puts [join $value_range_new]
产出
<-10 [-10,-8) [-8,-6) [-6,-4) [-4,-2) [-2,0) [0,2) [2,4) [4,6) [6,8) [8,10) >10
算法的较短变体。实际上一个 if
都不需要。
set section 5;
set value 2;
set this [expr {-$section * $value}]
set value_range_new [format {<%d} $this]
for {set i -$section} {$i < $section} {incr i} {
lappend value_range_new [format {[%d,%d)} $this [incr this $value]]
}
lappend value_range_new [format {>%d} $this]
puts [join $value_range_new]
在下面的代码中,我在 for
循环中生成一个字符串列表,如下所示:
set section 5;
set value 2;
set value_range_new "";
for { set i [expr -$section-1]} {$i <= $section} {incr i} {
if {$i < [expr -$section]} {
lappend value_range_new "\<[expr [expr $i+1]*$value]";
} elseif {$i == $section} {
lappend value_range_new "\>[expr $i*$value]";
} else {
lappend value_range_new "\[[expr $i*$value]\,[expr [expr $i +1]*$value]\)";
}
}
然后如果我puts
列表出来,结果如下:
<-10 {[-10,-8)} {[-8,-6)} {[-6,-4)} {[-4,-2)} {[-2,0)} {[0,2)} {[2,4)} {[4,6)} {[6,8)} {[8,10)} >10
令人困惑的一点是我不明白 {}
是从哪里来的。如果我像下面这样手动定义列表:
set a "\<-8 \[-8,-6\) \[-6,-4\) ";
看跌结果没有{}
。那么我的代码有什么问题,以及如何删除/
在 Tcl 中,您需要知道哪些命令要使用列表,哪些命令要使用字符串。 lappend
是一个列表命令。 puts
接受一个字符串。当您给 puts
一个列表时,Tcl 会将列表转换成它的字符串表示形式。这意味着您会看到一些额外的大括号和反斜杠,以保护具有特殊字符(如 [
和 ]
)的列表元素。
您可以使用 join
命令轻松地将列表转换为字符串。
对于构建字符串,format
命令可以提高可读性。
此外,您不需要接下来的expr
命令,使用括号;和 brace your expressions:
set section 5;
set value 2;
set value_range_new "";
for { set i [expr {-$section-1}]} {$i <= $section} {incr i} {
set this [expr {$i * $value}]
set next [expr {($i + 1) * $value}]
if {$i < -$section} {
lappend value_range_new [format {<%d} $next]
} elseif {$i == $section} {
lappend value_range_new [format {>%d} $this]
} else {
lappend value_range_new [format {[%d,%d)} $this $next]
}
}
puts [join $value_range_new]
产出
<-10 [-10,-8) [-8,-6) [-6,-4) [-4,-2) [-2,0) [0,2) [2,4) [4,6) [6,8) [8,10) >10
算法的较短变体。实际上一个 if
都不需要。
set section 5;
set value 2;
set this [expr {-$section * $value}]
set value_range_new [format {<%d} $this]
for {set i -$section} {$i < $section} {incr i} {
lappend value_range_new [format {[%d,%d)} $this [incr this $value]]
}
lappend value_range_new [format {>%d} $this]
puts [join $value_range_new]