List comprehensions: Difference between revisions
m
→{{header|Wren}}: Changed to Wren S/H
(Remove outdated and no longer supported OCaml solutions) |
m (→{{header|Wren}}: Changed to Wren S/H) |
||
(9 intermediate revisions by 3 users not shown) | |||
Line 21:
{{trans|Python}}
{{out}}
Line 275:
end mReturn</syntaxhighlight>
{{Out}}
<
=={{header|Arturo}}==
Line 397:
C doesn't have a built-in syntax for this, but any problem can be solved if you throw enough macros at it:
{{works with|GCC}}
The program below is C11 compliant. For C99 compilers note the change on line 57
<syntaxhighlight lang="c">▼
for (int i = f + 1; i <= t; i ++) { e = e->nx = listNew(sizeof i, &i); }▼
</syntaxhighlight>▼
<syntaxhighlight lang="c">▼
int i;▼
</syntaxhighlight>▼
<syntaxhighlight lang="c">
#include <stdlib.h>
Line 464 ⟶ 455:
List * intRangeList(int f, int t) {
List * l = listNew(sizeof f, &f), * e = l;
for (int i = f + 1; i <= t; i ++) { e = e->nx = listNew(sizeof i, &i); } // C11 compliant
▲//int i;
return l;
}
Line 611 ⟶ 604:
[x, y, z]
))
console.dir pyth 20</syntaxhighlight>
▲<code>pyth</code> can also be written more concisely as
▲<syntaxhighlight lang="coffeescript">pyth = (n) -> flatten (flatten ([x, y, z] for z in [y..n] when x*x + y*y is z*z for y in [x..n]) for x in [1..n])</syntaxhighlight>
=={{header|Common Lisp}}==
Line 1,045 ⟶ 1,036:
12 16 20
->
</pre>
=={{header|Insitux}}==
{{Trans|Clojure}}
(function pythagorean-triples n
(let n+1 (inc n))
(for x (range 1 n+1)
y (range x n+1)
z (range y n+1)
(unless (= (+ (* x x) (* y y)) (* z z))
(continue))
[x y z]))
(pythagorean-triples 20)
▲</syntaxhighlight>
{{out}}
<pre>
[[3 4 5] [5 12 13] [6 8 10] [8 15 17] [9 12 15] [12 16 20]]
</pre>
Line 1,935 ⟶ 1,947:
=={{header|Python}}==
List comprehension:▼
import itertools
n = 20
▲# List comprehension:
# A Python generator expression (note the outer round brackets),
# returns an iterator over the same result rather than an explicit list:
# A slower but more readable version: ▼
▲<syntaxhighlight 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)</syntaxhighlight>
# Or as an iterator:▼
▲A slower but more readable version:
# Alternatively we shorten the initial list comprehension but this time without compromising on speed.
▲<syntaxhighlight lang="python">[(x, y, z) for (x, y, z) in itertools.product(xrange(1,n+1),repeat=3) if x**2 + y**2 == z**2 and x <= y <= z]</syntaxhighlight>
# First we introduce a generator which generates all triplets:
def triplets(n):
▲Or as an iterator:
▲<syntaxhighlight lang="python">((x, y, z) for (x, y, z) in itertools.product(xrange(1,n+1),repeat=3) if x**2 + y**2 == z**2 and x <= y <= z)</syntaxhighlight>
▲Alternatively we shorten the initial list comprehension but this time without compromising on speed. First we introduce a generator which generates all triplets:
for x in xrange(1, n + 1):
for y in xrange(x, n + 1):
for z in xrange(y, n + 1):
yield x, y, z
Apply this to our list comprehension gives:▼
<syntaxhighlight lang="python">[(x, y, z) for (x, y, z) in triplets(n) if x**2 + y**2 == z**2]</syntaxhighlight>▼
▲# Apply this to our list comprehension gives:
Or as an iterator:▼
▲
▲# Or as an iterator:
# More generally, the list comprehension syntax can be understood as a concise syntactic sugaring
# of a use of the list monad, in which non-matches are returned as empty lists, matches are wrapped
# as single-item lists, and concatenation flattens the output, eliminating the empty lists.
# The monadic 'bind' operator for lists is concatMap, traditionally used with its first two arguments flipped.
# The following three formulations of a '''pts''' (pythagorean triangles) function are equivalent:
from operator import (add)
# pts :: Int -> [(Int, Int, Int)]
Line 2,029 ⟶ 2,042:
main()
▲</syntaxhighlight>
{{Out}}
<pre>[(3, 4, 5), (5, 12, 13), (6, 8, 10), (8, 15, 17), (9, 12, 15), (12, 16, 20)]
Line 2,067 ⟶ 2,081:
Raku has single-dimensional list comprehensions that fall out naturally from nested modifiers; multidimensional comprehensions are also supported via the cross operator; however, Raku does not (yet) support multi-dimensional list comprehensions with dependencies between the lists, so the most straightforward way is currently:
<syntaxhighlight lang="raku" line>my $n = 20;
say gather for 1..$n -> $x {
for $x..$n -> $y {
for $y..$n -> $z {
Line 2,074 ⟶ 2,088:
}
}</syntaxhighlight>
{{out}}
<pre>((3 4 5) (5 12 13) (6 8 10) (8 15 17) (9 12 15) (12 16 20))</pre>
Note that <tt>gather</tt>/<tt>take</tt> is the primitive in Raku corresponding to generators or coroutines in other languages. It is not, however, tied to function call syntax in Raku. We can get away with that because lists are lazy, and the demand for more of the list is implicit; it does not need to be driven by function calls.
Line 2,691 ⟶ 2,707:
=={{header|Wren}}==
Using a generator.
<syntaxhighlight lang="
(1..n-2).each { |x|
(x+1..n-1).each { |y|
|