3
$\begingroup$

The Python function

 def isPrime(n):
    return all(n % i for i in xrange(2, n))

checks if a number is a prime number by using all.

How can I write a function similar to all in Mathematica?

$\endgroup$
3
  • 1
    $\begingroup$ Have a look at PrimeQ. $\endgroup$ Commented Oct 24, 2012 at 11:09
  • 1
    $\begingroup$ I mean which function in mma eqv. python' all $\endgroup$
    – chyanog
    Commented Oct 24, 2012 at 11:17
  • 1
    $\begingroup$ While such questions doubtless have a theoretical value, one can wonder how fruitful it is, in general, to try to reproduce in one programming language the functions and paradigms of another. $\endgroup$
    – murray
    Commented Oct 24, 2012 at 16:08

1 Answer 1

7
$\begingroup$

initial side note: As J.M. correctly points out this is not an efficient implementation and serves only to illustrate behavior similar to the Python function all.

If you are looking for a similar definition to the Python code you give, then you could use this:

 isPrime[n_] := And @@ Table[Mod[n, i] != 0, {i, Range[2, n - 1]}]

This creates a table of either True or False for each i in the range, and the And@@ means it replaces the head of the list, turning {True,False,True,...} (Which is equivalent to List[True,False,True,...]) into And[True,False,True,...] and thus evaluates to true only if they are all true.

You can then find primes under 20 using:

Select[Range@20, isPrime]
{1, 2, 3, 5, 7, 11, 13, 17, 19}

This however includes 1, which it should not. You could also just use the build in prime checker:

Select[Range@20, PrimeQ]
{2, 3, 5, 7, 11, 13, 17, 19}

Update

To elaborate, all in python takes an iterable object and returns true if all iterations are true. For the Mathematica code, And@@ is used on a realised list of booleans and returns True if they are all true. So they are not strictly the same, but typically in Mathematica you do not have language specified "iterables".

You could pass around unevaluated iteration specfications quite simply however, allowing you to iterate in any way you see fit in functions that take these specifications as input. For instance implementing an all-like function that can short circuit on the very first False found:

 SetAttributes[iterable, HoldAll]

 myAll[iterable[exp_, {var_, lower_, upper_}]] := 
 Module[{run = upper >= lower, i = lower},
 While[run,
  If[exp /. var -> i,
   If[i == upper, Return[True], i++], Return[False]];
 ]; True
 ]

Allowing the prime function you gave to be defined as:

 dprimeQ[n_] := myAll[iterable[Mod[n, i] != 0, {i, 2, n - 1}]]

 Select[Range@20, dprimeQ]
{1,2,3, 5, 7, 11, 13, 17, 19}

Which still includes 1 however.

$\endgroup$
8
  • $\begingroup$ This is exactly what I want,Thanks. $\endgroup$
    – chyanog
    Commented Oct 24, 2012 at 11:24
  • $\begingroup$ isPrime[] is not very efficient compared to the built-in PrimeQ[], of course. Here's an alternative definition: isPrime[n_Integer?Positive] := And @@ Thread[Mod[n, Range[2, n - 1]] != 0] $\endgroup$ Commented Oct 24, 2012 at 11:28
  • $\begingroup$ @J.M. True, but the question wasn't about an efficient implementation but one that is similar to the Python one. I felt that this was the closest you could get without actually going into handling the iteration unevaluated, and staying close to "typical" Mathematica code. $\endgroup$
    – jVincent
    Commented Oct 24, 2012 at 11:36
  • $\begingroup$ Additionally, here's a "short-circuiting" version: isPrime[n_Integer?Positive] := Catch[Fold[If[! #2, Throw[#2], #1 && #2] &, True, Thread[Mod[n, Range[2, n - 1]] != 0]]] $\endgroup$ Commented Oct 24, 2012 at 11:48
  • $\begingroup$ @J.M. Your last solution doesn't seem to actually short circuit. You are still computing all the comparisons at once (Thread[Mod[n, Range[2, n - 1]] != 0]) but then short circuiting the following traversal (which I suspect And already does internally). Consider a slower comparison, for instance (Pause[1];Mod[n,i]!=0) and test with isPrime[8]. For your version it takes 6 seconds on my system, while the solution posted in my answer returns after just 1 second. $\endgroup$
    – jVincent
    Commented Oct 24, 2012 at 12:03

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.