Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

for loop with 2 iterators and 2 ranges

I am a newbie of Python and dealing with a prime generator. The algorithm i wanna use is Sieve of Atkin.

At this moment, I am trying to follow the pseudo code of the algorithm as my practice. However, I have faced a problem and I can't find any reference about it. (Maybe I am not good at searching...). In the pseudo code, for (x, y) in [1, √limit] × [1, √limit]:... makes me confused. I know what it means but don't know how to translate this code into Python code.

Sorry if my question is not appropriate, and thanks for the help. :)

Below is a part of my code.

itx = iter(range(1, int(limit**0.5)))
ity = iter(range(1, int(limit**0.5)))
for x, y in zip(itx, ity):
    n = 4*(x**2)+(y**2)
    if n <= limit and (n%12 == 1 or n%12 == 5):
        sieve[n] = not sieve[n]

    n = 3*(x**2)+(y**2)
    if n <= limit and n%12 == 7:
        sieve[n] = not sieve[n]

    n = 3*(x**2)-(y**2)
    if x > y and n <= limit and n%12 == 11:
        sieve[n] = not sieve[n]

    itx.next()
    ity.next()
like image 855
PCHC Avatar asked Mar 09 '26 14:03

PCHC


2 Answers

for (x, y) in [1, √limit] × [1, √limit] should be translated to a product:

for x in itx:
    for y in ity:

or using itertools.product():

from itertools import product

for x, y in product(itx, ity):

Note that you do not need to call .next() on the iterators! Remove the itx.next() and ity.next() lines, unless you mean to skip generated values. The for construct advances the iterators for you.

like image 142
Martijn Pieters Avatar answered Mar 12 '26 03:03

Martijn Pieters


Instead of zip(itx, ity), you need to use itertools.product(itx, ity).

zip iterates over two iterators in parallel (operation known as convolution), yielding pairs of matching items and ending iteration when the shortest iterator is exhausted. itertools.product iterates over the Cartesian product of the two iterators, yielding pairs of all combinations of items from one and the other set. The latter is what the × operator refers to.

As Martijn Pieters pointed out, manually calling .next() on the iterators is incorrect, since for advances them itself, and doing it yourself you end up only processing every second item of the iterable. Also, iter(range(...)) is unnecessary — simply use xrange (or range in Python 3).

like image 21
user4815162342 Avatar answered Mar 12 '26 03:03

user4815162342



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!