List comprehensions: Difference between revisions

add Tcl
(→‎{{header|Python}}: removed the generator function example as it is not a comprehension and is syntactically not close.)
(add Tcl)
Line 115:
 
<lang python>((x,y,z) for x in xrange(1,n+1) for y in xrange(x,n+1) for z in xrange(y,n+1) if x**2 + y**2 == z**2)</lang>
 
=={{header|Tcl}}==
Tcl does not have list comprehensions built-in to the language, but they can be constructed.
<lang tcl>package require Tcl 8.5
 
# from http://wiki.tcl.tk/12574
proc lcomp {expression args} {
# Check the number of arguments.
if {[llength $args] < 2} {
error "wrong # args: should be \"lcomp expression var1 list1\
?... varN listN? ?condition?\""
}
 
# Extract condition from $args, or use default.
if {[llength $args] % 2 == 1} {
set condition [lindex $args end]
set args [lrange $args 0 end-1]
} else {
set condition 1
}
 
# Collect all var/list pairs and store in reverse order.
set varlst [list]
foreach {var lst} $args {
set varlst [concat [list $var] [list $lst] $varlst]
}
 
# Actual command to be executed, repeatedly.
set script {lappend result [subst $expression]}
 
# If necessary, make $script conditional.
if {$condition ne "1"} {
set script [list if {[expr $condition]} $script]
}
 
# Apply layers of foreach constructs around $script.
foreach {var lst} $varlst {
set script [list foreach $var $lst $script]
}
 
# Do it!
set result [list]
{*}$script ;# Change to "eval $script" if using Tcl 8.4 or older.
return $result
}
 
set range {1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20}
puts [lcomp {$x $y $z} x $range y $range z $range {$x < $y && $x**2 + $y**2 == $z**2}]</lang>
<pre>{3 4 5} {5 12 13} {6 8 10} {8 15 17} {9 12 15} {12 16 20}</pre>
Anonymous user