3

I want to have something like a double conditional I want to include in a forloop, in order to reduce computation time I want to do something like the following:

for i WHERE i % 2 == 0 in range(0,(realbignumber/2)):
    if i % realbignum == 0: do some stuff

I am mostly uncertain on the proper way to do that 'where' type statement in the forloop? I'm sure there are probably better approaches to take to reduce computation time (i'm trying to do a prime factorization of realbignum) and will start by getting a list of divisors, then check for primeness. Once I get the i%2==0 'where' clause figured out I plan on implementing something like 'for i where i is prime in range....do stuff. I'm working in python 2 but am fine with python 3 approaches as well.

thefourtheye
  • 206,604
  • 43
  • 412
  • 459
Abraxas
  • 359
  • 1
  • 7
  • 24
  • as you are trying to do a prime factorization, take a look at this: [how to implement an efficient infinite generator of prime numbers in python](http://stackoverflow.com/questions/2211990/how-to-implement-an-efficient-infinite-generator-of-prime-numbers-in-python). – Copperfield Jan 13 '16 at 04:15

2 Answers2

4

Use a generator expression, like this

for i in (num for num in xrange(realbignumber / 2) if num % 2 == 0):

For this particular case, you can actually specify the step argument in xrange itself, like this

for i in xrange(0, realbignumber / 2, 2):

Please note that I have used xrange instead of range function. Because range function in Python 2.x create a list of numbers, where as xrange creates just an xrange object. So xrange is suitable for very long ranges, as it is highly memory efficient.


If the input number is too big to fit in Python's int, then you can roll your own simplified range function, with the help of generators, like this

>>> def my_range(start, stop, step=1):
...     current = start
...     while current < stop:
...         yield current
...         current += step
... 
>>> [num for num in my_range(0, 10)]
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]

Or you can use the itertools version, shown by the ShadowRanger, like this

>>> from itertools import islice, count
>>> def bigxrange(start, stop, step=1):
...     return islice(count(start, step), (stop - start + step - 1))
... 
>>> list(bigxrange(0, 10))
[0, 1, 2, 3, 4, 5, 6, 7, 8, 9]
thefourtheye
  • 206,604
  • 43
  • 412
  • 459
  • Hmm, unfortunately my number is too big for xrange, I'm getting "OverflowError: Python int too large to convert to C long" Any idea on getting around that? -- I'm aware that this likely won't compute in a suitable time, I'm currently attempting to watch output as it goes to make sure things are working as expected and will then work on optimizing, still new to this code thing =) – Abraxas Jan 13 '16 at 03:16
  • 1
    @Abraxas You can use the generator function, like I have shown in the updated answer. – thefourtheye Jan 13 '16 at 03:20
  • 1
    @Abraxas: No good workaround. Best you can do is build a `bigxrange` from `itertools` parts: `from itertools import islice, count`, `def bigxrange(start, stop, step=1): return islice(count(start, step), (stop - start + step - 1) // step)` – ShadowRanger Jan 13 '16 at 03:20
  • Thanks guys! Output is flying across the screen now. =D – Abraxas Jan 13 '16 at 03:21
  • 1
    @thefourtheye: The `itertools` approach is likely to be much closer to the speed of `xrange` by pushing all the work to C. – ShadowRanger Jan 13 '16 at 03:21
  • @ShadowRanger I agree. Thanks for pointing it out :-) I included that also in the answer. – thefourtheye Jan 13 '16 at 03:24
  • I'm having a bit of an issue with the bigxrange implementation, I have this line: for i in bigxrange(0, (thenum / 2), 2): based on the code provided in the definition in the answer but I am receiving: ValueError: Stop argument for islice() must be None or an integer: 0 <= x <= maxint. – Abraxas Jan 13 '16 at 03:30
  • 1
    @Abraxas Hmmm, then you can settle with the `my_range` implementation or switch to Python 3, where this int restriction is not there :P – thefourtheye Jan 13 '16 at 03:33
0

Maybe this Stackoverflow post can help you.

With python3, according to this discussion and this python3 documentation reference, that code should work.

Community
  • 1
  • 1
Isaque Alves
  • 1
  • 1
  • 2