1

I saw the tutorial on Youtube on how to solve Project Euler`s problem 7 and have found this piece of code:

    numbers_prime_to_find = 10001
    x = 2
    list_of_primes = []
    while (len(list_of_primes) < numbers_prime_to_find):
        if all(x % prime!=0 for prime in list_of_primes):  # for prime in list_of_primes:

            list_of_primes.append(x)  # if x%prime
        x+=1
    print(list_of_primes[-1])

main()

It seems pretty obvious to me except this one line: if all(x % prime!=0 for prime in list_of_primes)

Can someone try to explain this to me as I am struggling badly to find information about this method? Thanks in advance ^-^

Maksim Levchenko
  • 87
  • 1
  • 1
  • 9

3 Answers3

1

x % prime!=0 for prime in list_of_primes is called a "generator expression".

A related syntax is a "list comprehension". [x % prime!=0 for prime in list_of_primes] would make a new list, the same length as list_of_primes. For each element in list_of_primes, the corresponding element in the new list would be x % prime != 0, where prime is the list element.

The list comprehension produces the same result as the following:

newList = []
for prime in list_of_primes:
    newList.append(x % prime != 0 )

A "generator expression" is almost the same, but produces a one-time iterable that is computed lazily.

So all(x % prime!=0 for prime in list_of_primes) is true if, for every element in list_of_primes, x % prime != 0.

rlbond
  • 65,341
  • 56
  • 178
  • 228
  • I am sorry if the question is kinda stupid, but can u explain how we can divide by prime, if we do not define the list_of_primes and it has a zero value when the program is started. Then we start a for loop and this part confuses me – Maksim Levchenko Jul 30 '20 at 23:10
  • I mean, the first iteration confuses me, how can we .append(x), cause if we divide 2 by none in the list what do we get?? – Maksim Levchenko Jul 30 '20 at 23:17
0

When you write this:

(x + 1 for x in [1, 2, 3])

it is called a "generator" and is like a for loop. It kind of returns:

(2, 3, 4)

It actually returns a "generator" object that you can treat like most other iterables but it is easiest to understand first as a normal tuple.

In your case, you are doing:

(x % prime!=0 for prime in list_of_primes)

so the function being done to every element of the list of primes is x % prime != 0.

This is calculating x % prime which is "x modulo prime" which is the remainder left over when you divide x by prime.

For example, 7 % 3 is 1 because 3 goes into 7 2 times, with remainder 1.

Then you see if this remainder equals 0.

The all function accepts an iterable and returns True if all elements are True and False if all elements are False.

So the if statement only succeeds if no prime number in the list of primes divides into x with 0 remainder.

To say that another way, the if statement only succeeds if no prime in the list is a "factor" of x.

Peaceful James
  • 1,807
  • 1
  • 7
  • 16
  • 2
    There's no such thing as a "tuple comprehension". `(x+1 for x in [1,2,3])` is a generator expression. – khelwood Jul 30 '20 at 22:56
  • I am sorry if the question is kinda stupid, but can u explain how we can divide by prime, if we do not define the list_of_primes and it has a zero value when the program is started. Then we start a for loop and this part confuses me – Maksim Levchenko Jul 30 '20 at 23:10
  • I mean, the first iteration confuses me, how can we .append(x), cause if we divide 2 by none in the list what do we get?? – Maksim Levchenko Jul 30 '20 at 23:17
  • Well you have to know that `all([])` will evaluate to `True`. That is, `all` is `True` for an empty iterator. So in the first iteration, it is like doing `all(())` which is `True`. So `2` gets appended as the first prime. – Peaceful James Jul 31 '20 at 00:29
  • Why is this being downvoted? – Peaceful James Aug 02 '20 at 11:36
0

The all() function in python takes in an iterable object like a dictionary or list and returns true or false

It returns true only if all the values in the iterable object is true

In all(x % prime!=0 for prime in list_of_primes), the all function is finding the remainder for x/prime where prime is an element in the list list_of_primes

If any number divides perfectly by a prime then the all() returns false( x % prime = 0 ) and doesn't add to the list

Vinod Kumar
  • 1,383
  • 1
  • 12
  • 26
  • I am sorry if the question is kinda stupid, but can u explain how we can divide by prime, if we do not define the list_of_primes and it has a zero value when the program is started. Then we start a for loop and this part confuses me – Maksim Levchenko Jul 30 '20 at 23:05