0

Get a vector consisting of prime numbers as output from given input vector. Worked in Python, wherein I appended each prime number from the input list to an empty list, but not getting correct output in R

Python Code:

def get_prime(input_list):
    output_list = []
    for num in input_list:
        for i in range(2, num):
                if num%i == 0:
                    break
        else:   
            output_list.append(num)
    return output_list

Output:

get_prime([3,4,5,6,7,8])
[3, 5, 7]

R Code:

get_prime <- function(input_number_vector){
  prime = c()
  for(num in input_number_vector){
    for(div in 2:(num-1)){ if(num %% div == 0) break 
                           else prime = c(prime,num)
                                                   }
    }
  prime
}

Output:

x <- c(3,4,5,6,7,8)
> get_prime(x)
[1] 3 5 5 5 7 7 7 7 7

Expected Output:

3,5,7

Looks like the odd numbers: 3, 5, 7 are appended once for each modulus condition check. i.e. 3 once with divisor of 2, 5 thrice with divisors 2,3,4 and 7 with divisors 2,3,4,5,6. Could someone let me know where I am going wrong and if R works differently than Python in this regard.

Karthik S
  • 11,348
  • 2
  • 11
  • 25
  • The R code is simply not doing the same as the Python code. They are similar but not identical (the R code appends to the vector inside the inner loop). – Konrad Rudolph Mar 25 '19 at 11:39
  • You're updating the `prime` vector each time the remainder is non-zero. If you try with some odd non-prime numbers, this code will print the that number many times for as many numbers exceed the first divisor, starting from 2. – yarnabrina Mar 25 '19 at 11:43

2 Answers2

1

for..else is a construct pretty unique to Python. What you are saying that if we do not break in the for, we append. R has no such construct, and as such the else is matched with the if. You also seem to be interpreting the space ruling of the Python syntax to be the same here - it is again, a unique Python thing. Any other language I know which encounters an if...else will interpret them together Regardless of newlines/spacing between them, which is what you mahve have not expected.

The easiest way to do this without the special Python construct is to use a flag before the loop, is_prime<-1, and set it to 0 if you find it is not. Then out of the loop check if(is_prime), and append if so. Amending the body of the outer loop results in:

is_prime<-TRUE
for(div in 2:(num-1)) {
    if(num %% div == 0) {
        is_prime<-FALSE
        break 
    }
}
if (is_prime) prime = c(prime,num)
kabanus
  • 24,623
  • 6
  • 41
  • 74
0

There are obviously better ways to code this up but as far as debugging your code is concerned here are some observations.

else in Python code is outside if block whereas in R code you are presenting it in at the same level as if. Having else like this in Python is permitted whereas the same is not allowed in R. If you try to use the same thing in R, you will get an error. (by same thing I mean having else without an if).

Another point is to have check to add a number in prime only if it has exhausted the entire 2:(num-1) . Incorporating these two changes we can write your function as

get_prime <- function(input_number_vector){
   prime = c()
   for(num in input_number_vector){
     for(div in 2:(num-1)){ 
       if(num %% div == 0) break 
     }
     if (div == num - 1)
        prime = c(prime,num)
     }
     prime
 } 

x <- c(3,4,5,6,7,8)
get_prime(x)
#[1] 3 5 7
Ronak Shah
  • 377,200
  • 20
  • 156
  • 213