To operate on each element of a list, returning a modified list various languages have explicit constructs.
In Perl there’s map:
perl -e 'my @a = (1..4); print join(q( ), map { $_ * $_ } @a)'
1 4 9 16
In Python there’re list comprehensions:
>>> a = (1,2,3,4)
>>> [el*el for el in a]
[1, 4, 9, 16]
What’s the most efficient way to do this in Tcl?
I can come up with the usual foreach loop.
set l {}
foreach i {1 2 3 4} {
lappend l [expr $i * $i]
}
puts $l
1 4 9 16
Is this the fastest way?
Regarding mem efficiency this builds up a second list, one by one. If I don’t need the list permanently is there a more efficient way?
And, finally, is there something that’s shorter?
I couldn’t find infos here or in the http://wiki.tcl.tk
Answer:
As Donal Fellows has answered, most importantly for speed tests, things should be wrapped in a proc {} since Tcl then can optimize. For Tcl, a “map” function is discussed as a future enhancement. With this hint and further searching I found http://wiki.tcl.tk/12848
The most efficient method is this:
If the list is short (e.g., a few hundred elements) the cost of allocating a new list is minimal though, so you can use this (simpler) version instead:
Note that the
foreachcommand is only fast if placed in a procedure (or lambda expression or method) and expressions are only fast if placed in{braces}. Also, don’t speculate, measure: take care to use thetimecommand to find out how fast your code really is.