循环遍历2的幂

4

我希望编写一个for循环,用于迭代每个循环的2的幂。

例如,我需要一个如下范围的循环:

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

我该怎么做呢?


在网上有很多关于如何做这个的好信息。从Python的基础开始。我保证,如果你只是阅读一些关于Python的文档/教程,你一定会遇到for循环和如何做这个的内容。 - Philip
2
你尝试过使用谷歌搜索,或者阅读教科书,或者自己动手解决问题了吗? - TigerhawkT3
2
我也可以问一下,“2、4、8、16”是如何成为2的倍数范围的,或者为什么这里没有代码或研究工作…… - TigerhawkT3
1
谷歌搜索“迭代二的幂”将会得到这个作为第一个结果。而且,之后在谷歌上的其他链接实际上更糟糕。对于一个合理的问题感到失望。 - orangepips
6个回答

8
您可以使用生成器表达式,以便根据需要生成数字,而不会浪费内存: (生成器表达式的详细信息)
>>> for x in (2**p for p in range(1, 11)):
...    print(x)

2
4
8
16
32
64
128
256
512
1024

在Python 2中,您可以使用xrange而不是range来保持其作为生成器并避免创建不必要的列表。
如果您想输入实际的停止点而不是停止幂,这可能是最简单的方法:
from itertools import count
for x in (2**p for p in count(1)):
    if x > 1024:
        break
    print(x)

你可以把所有内容都放在一行中:
from itertools import count, takewhile
for x in takewhile(lambda x: x <= 1024, (2**p for p in count(1))):
    print(x)

但这变得有点傻了(而且不太易读)。

这与答案的不同之处在于,您的范围是限制的平方根,而我的答案范围是直接到达限制本身。这是一个不同的用例。OP没有指定他们想要范围达到2 ** N(您的方法)还是达到K(我的方法)。但如果在Python 3上运行,则与AndrewSmiley发布的内容完全相同。 - Martijn Pieters
@MartijnPieters其他答案没有使用生成器表达式,这就是我要说明的。它简单而高效。 - endolith
但是它并不比使用生成器更有效;我的方法不需要计算所需结束值的平方根。 - Martijn Pieters
@MartijnPieters 是的,它并不更高效,但更简单。这不是一个平方根,而是一个对数。如果您想直接输入停止点,那么它会变得不合理复杂。 - endolith
哎呀,是的,我是指log2。 - Martijn Pieters

4

您需要创建自己的函数:

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

这里使用了左移操作;如果您认为更清晰的话,也可以使用start *= 2

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

1
抱歉,我无法想出任何答案来回答基本上是“如何将两个数字相加”的问题(start <<= 1 看起来很酷,但它等同于 start = start + start),对于那些已经花费了几分钟时间使用 Python 解释器的人来说,这样的回答并没有什么帮助。 - TigerhawkT3
@TigerhawkT3:抱歉你觉得这没有帮助;是的,这个问题很基础,他们可能混淆了for循环和while循环。我希望您能根据答案本身来评价,而不是问题的质量,无论如何,这就是我所做的。 - Martijn Pieters
正如我所说,对于这样的问题,我的看法是提供答案并不会有什么帮助 - 即使对于原帖作者来说也是如此,他们可能明天就会回来收集代码而没有学到任何东西。 - TigerhawkT3

4
counter = 2

while counter <= 1024:
    print counter
    counter *= 2

2
请解释您的代码是做什么的,以及为什么它可以解决问题。仅包含代码的答案(即使它能工作)通常不会帮助提问者理解他们的问题。 - SuperBiasedMan
1
@SuperBiasedMan 这里没有什么需要解释的。这不是一个直截了当的答案吗? - Vishal
4
问题并不是很复杂,但是提问者显然没有理解,所以才需要问这个问题。如果能给出解释,这个回答将更好。 - SuperBiasedMan
2
@Vishal 这个问题也非常直接,所以我认为它仍然是必要的,假设我们认为这个问题是一个有效的问题! - Rob Grant

2

您想要在每个循环中迭代2的幂次方,

看了您的例子,可以这样表述:

创建一个循环,将初始值乘以2,直到达到1024。

ii = 2
while ii <= 1024: 
    print(ii)
    ii = ii*2

0

这个不需要你自己写函数,只需要使用一个lambda表达式就可以了

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

输出看起来像这样

1
2
4
8
16
32
64
128
256
512
1024

如果你知道需要到达的2的幂次方,那么可以直接到达。如果不知道,可以像这样到达最大可存储的整数:

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

输出看起来像这样

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

1
由于您使用了 print,看起来您正在使用 Python 2。在 Python 2 中使用 range()map() 意味着您会预先生成 列表range() 生成一个包含从 0 到 floor(squareroot(N)) 的所有整数的列表,然后 map() 生成另一个整数列表,每个整数都是二的幂次方。只有在这些数字上迭代之后才能进行操作。只有在 Python 3 中,range()map() 才会按需生成数字。 - Martijn Pieters

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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接