如何在Tcl中有效地(mem/time)修改列表的所有元素



要对列表的每个元素进行操作,返回修改后的列表,各种语言都有明确的构造。

Perl中有map:

perl -e 'my @a = (1..4); print join(q( ), map { $_ * $_ } @a)'
1 4 9 16

在Python中有列表推导式:

>>> a = (1,2,3,4)
>>> [el*el for el in a]
[1, 4, 9, 16]

在Tcl中最有效的方法是什么?我可以用通常的foreach循环。

set l {}
foreach i {1 2 3 4} {
    lappend l [expr $i * $i]
}
puts $l
1 4 9 16
这是最快的方式吗?

考虑到内存效率,这建立了第二个列表,一个接一个。如果我不需要这个列表,有没有更有效的方法?

最后,有没有更短的?我无法在这里或http://wiki.tcl.tk

找到信息。

答:

正如Donal Fellows所回答的那样,对于速度测试最重要的是,应该将东西包装在proc{}中,因为这样Tcl就可以进行优化。对于Tcl,"映射"函数将作为未来的增强进行讨论。通过这个提示和进一步搜索,我找到了http://wiki.tcl.tk/12848

最有效的方法是:

set idx 0
foreach item $theList {
    lset theList $idx [expr {$item * $item}]
    incr idx
}

如果列表很短(例如,几百个元素),分配一个新列表的成本是最小的,所以你可以使用这个(更简单的)版本:

foreach item $theList {
    lappend newList [expr {$item * $item}]
}

注意,如果放在过程(或lambda表达式或方法)中,foreach命令只有快,如果放在{括号}中,表达式只有快。此外,不要推测,测量:注意使用time命令来找出你的代码到底有多快。

嗯,有一些更短的(使用tcllib struct::list包),但不一定更快。

package require struct::list
puts [struct::list mapfor x $data { expr {$x * $x} }]

相关内容

  • 没有找到相关文章

最新更新