我有一个如下的tcl列表。
set mylist [list a b c d e]; # could be more
现在我正在进行一些处理,如果列表包含项目" c"," d"," e"。但是,当且仅当列表具有以下任一值时,我才需要跳过该处理:
set mylist [list a];
OR
set mylist [list b];
OR
set mylist [list a b];
因此,如果mylist是以上三种中的任何一种,我跳过处理。但是,假设列表中除了上述三种组合之外还有其他任何值,我都会进行处理。
如果列表中包含三种组合中的任何一种,最有效的搜索方式是什么。
我有满足我要求的基本代码,但我正在寻找更有效的方法,因为我对tcl容器不太熟悉。
set mylist [list a];
if {[llength $mylist] == 2 && ([lindex $mylist 0] eq "a" || [lindex $mylist 0] eq "b") && ([lindex $mylist 1] eq "a" || [lindex $mylist 1] eq "b")} {
puts "1. skip the processing"
} elseif {[llength $mylist] == 1 && ([lindex $mylist 0] eq "a" || [lindex $mylist 0] eq "b")} {
puts "2. skip the processing"
} else {
puts "Do the processing"
}
我想知道是否有其他有效的方法来执行相同的操作。
答案 0 :(得分:2)
if {$mylist in {a b {a b}}} {
puts "skip the processing"
}
列表不是字符串,但我们通常可以将列表与字符串进行比较以获得相等和顺序。具有单个元素“a”的列表与字符串“a”相当。如果您想知道给定字符串是否等于问题中的任何列表,最简单的方法是检查列表的值是否是列表{a b {a b}}
的成员。
注意: 此特定解决方案一般不会解决列表相等的所有方面。它适用于有效的情况。
<强>效率强>
将列表与字符串进行比较是否真的有效,这会导致自动重复重建数据的内部表示(“闪烁”)。实际上,它是。如果比较程序
proc foo1 mylist {
set a 0
if {$mylist in {a b {a b}}} {set a 92}
return $a
}
proc foo2 mylist {
set a 0
if {$mylist in [list [list a] [list b] [list a b]]} {set a 92}
return $a
}
然后foo1
似乎比foo2
更快(不同的机器可能产生不同的结果)。
在条件评估代码中构建一个列表似乎并没有增加太多时间。这个程序
proc foo3 mylist {
set a 0
set x [list [list a] [list b] [list a b]]
if {$mylist in $x} {set a 92}
return $a
}
速度介于foo1
和foo2
之间,但不会明显快于foo2
。
也可以通过调用lsearch
:
proc foo4 mylist {
set a 0
set x [list [list a] [list b] [list a b]]
if {[lsearch $x $mylist] >= 0} {set a 92}
return $a
}
proc foo5 mylist {
set a 0
set x [list [list a] [list b] [list a b]]
set i [lsearch $x $mylist]
if {$i >= 0} {set a 92}
return $a
}
与foo2
和foo3
相当。
(如果需要说明,lsearch
比in
运算符更通用,提供例如不区分大小写的查找,正则表达式查找等。如果您需要这些内容,{{1}是最好的选择。)
在另一台机器上安排程序后,我删除了大部分关于速度的观察和理论,结果显示出截然不同的结果。但是,lsearch
在这两台机器上的速度始终更快。由于该代码比其他替代方案更简单,我想说这是实现它的方法。但可以肯定的是,人们需要使用自己的机器,白名单和要执行的代码来计算程序。
最后,如果I / O发生在程序内部,那么这一切都不重要,因为I / O会比其他任何东西慢得多。