For loop iterate over powers of 2
Asked Answered
U

6

5

I want to write a for loop that will iterate over the powers of 2 for each loop.

For example I would want a range like this:

2, 4, 8, 16, ... , 1024

How could I do this?

Uncounted answered 7/8, 2015 at 8:10 Comment(4)
There are plenty of good information about how to do this at the web. Start with the basics of python. I will guarantee you that you will stumble upon for loops and how to do this if you just read some documentation/tutorial about pythonDogmatic
Have you tried using Google, or reading your textbook, or anything at all on your own?Silvers
I could also ask how "2, 4, 8, 16" is a range of multiples of 2, or why there's no code or research effort here...Silvers
Googling "iterate over powers of two" has this as the first result. And, other links thereafter on Google are actually worse. smh for a reasonable question.Ynez
R
5
counter = 2

while counter <= 1024:
    print counter
    counter *= 2
Radiosurgery answered 7/8, 2015 at 8:15 Comment(4)
Please explain what your code does and why it will solve the problem. An answer that just contains code (even if it's working) usually wont help the OP to understand their problem.Leckie
@Leckie there is nothing to explain here. Isn't it straight forward answer?Radiosurgery
It's not very complicated, but the OP clearly didn't understand it if they needed to ask the question. And an explanation would make this a better answer.Leckie
@Radiosurgery the question is also very straightforward, so I'd say it's still needed, assuming we consider the question to be a valid one!Advantageous
P
8

You can use a generator expression so that it generates the numbers as needed and they don't waste memory:

>>> for x in (2**p for p in range(1, 11)):
...    print(x)

2
4
8
16
32
64
128
256
512
1024

In Python 2, you can use xrange instead of range to keep it as a generator and avoid creating unnecessary lists.

If you want to enter the actual stop point instead of the power to stop at, this is probably the simplest way:

from itertools import count
for x in (2**p for p in count(1)):
    if x > 1024:
        break
    print(x)

You could put it all in one line:

from itertools import count, takewhile
for x in takewhile(lambda x: x <= 1024, (2**p for p in count(1))):
    print(x)

but that's becoming silly (and not very readable).

Paregmenon answered 23/6, 2016 at 0:7 Comment(5)
This only differs from answer in that you range up to the square root of the limit, where my answer ranges up to the limit itself. A different use-case. The OP didn't specify if they wanted to range up to 2**N (your approach) or to up to K (my approach). If run on Python 3, this is exactly the same thing that AndrewSmiley posted however.Yippee
@MartijnPieters None of the other answers uses a generator expression, which is what I'm illustrating. It's simple and efficientParegmenon
But it is no more efficient than using a generator; mine doesn't require you to calculate the squareroot of the desired end value however.Yippee
@MartijnPieters Yes it's not more efficient, but it's simpler. It's not a square root, it's a logarithm. Yes, it becomes unreasonably complicated if you want to be able to enter stop point directly.Paregmenon
Ick, yes, I meant the log2.Yippee
Y
5

You'll need to create your own function:

def doubling_range(start, stop):
    while start < stop:
        yield start
        start <<= 1

This uses a left-shift operation; you could also use start *= 2 if you find that clearer.

Demo:

>>> def doubling_range(start, stop):
...     while start < stop:
...         yield start
...         start <<= 1
... 
>>> for i in doubling_range(2, 1025):
...     print i
... 
2
4
8
16
32
64
128
256
512
1024
Yippee answered 7/8, 2015 at 8:14 Comment(3)
Sorry, but I can't think of any way for an answer to what's basically "how do I add two numbers together" (start <<= 1 looks cool, but it's equivalent to start = start + start) to be helpful to anyone who's spent more than a few minutes with the Python interpreter.Silvers
@TigerhawkT3: Sorry you found this to be unhelpful; yup, the question is basic, and they probably got confused with a for loop rather than use a while loop. I'd hoped you judged answers on their own, separate from the quality of the question, however, it is what I do at any rate.Yippee
As I said, the answer to such a question is not helpful, in my opinion - not even to the OP, who will probably come back tomorrow to collect the code and not learn anything.Silvers
R
5
counter = 2

while counter <= 1024:
    print counter
    counter *= 2
Radiosurgery answered 7/8, 2015 at 8:15 Comment(4)
Please explain what your code does and why it will solve the problem. An answer that just contains code (even if it's working) usually wont help the OP to understand their problem.Leckie
@Leckie there is nothing to explain here. Isn't it straight forward answer?Radiosurgery
It's not very complicated, but the OP clearly didn't understand it if they needed to ask the question. And an explanation would make this a better answer.Leckie
@Radiosurgery the question is also very straightforward, so I'd say it's still needed, assuming we consider the question to be a valid one!Advantageous
D
3

You say you want to iterate over the powers of 2 for each loop,

Seeing your example, the formulation could be:

Make a loop that multiply the initial by 2 untill it reach 1024.

ii = 2
while ii <= 1024: 
    print(ii)
    ii = ii*2
Desrosiers answered 7/8, 2015 at 8:15 Comment(0)
T
0

You don't need your own function for this one, just use a lambda

import sys
from math import log
for i in map(lambda v : pow(2,v), range(0,log(1024, 2))):
    print i

output looks like

1
2
4
8
16
32
64
128
256
512
1024

If you know what power of 2 you need to go to. If you don't, you could just go up to the largest storable int, like this:

from math import log
import sys
for i in map(lambda v : pow(2,v), range(0,int(log(sys.maxint, 2)))):
    print i

Output looks like

1
2
4
8
16
32
64
128
256
512
1024
2048
4096
8192
16384
32768
65536
131072
262144
524288
1048576
2097152
4194304
8388608
16777216
33554432
67108864
134217728
268435456
536870912
1073741824
2147483648
4294967296
8589934592
17179869184
34359738368
68719476736
137438953472
274877906944
549755813888
1099511627776
2199023255552
4398046511104
8796093022208
17592186044416
35184372088832
70368744177664
140737488355328
281474976710656
562949953421312
1125899906842624
2251799813685248
4503599627370496
9007199254740992
18014398509481984
36028797018963968
72057594037927936
144115188075855872
288230376151711744
576460752303423488
1152921504606846976
2305843009213693952
4611686018427387904
Turnery answered 20/6, 2016 at 20:1 Comment(1)
Since you use print, you appear to be using Python 2. Using range() and map() on Python 2 means you produce lists up-front. range() produces a list with all the integers from 0 to floor(squareroot(N)), and then map() produces another list of integers, each a power of two. Only then do you iterate over those numbers. Only in Python 3 do range() and map() produce the numbers on demand.Yippee
K
0
def ram_size(min_size: int, step: int, max_size: int):
    """list generator from min to max powered by step"""
        size = min_size
        while size <= max_size:
            yield size
            size *= step
Karikaria answered 6/4, 2023 at 20:50 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.