我构建了一个简单的Python程序来查找输入是否为2的幂。我有两个功能,power_of_two
和play_again
。运行power_of_two
后,play_again
会运行并重新运行power_of_two
这是我的代码:
num = int(raw_input('Input a number (type 0 to quit): '))
def power_of_two(x):
y=1
z=[]
while y < x:
y=y*2
z.append(y)
if x in z or x == 1:
print 'true'
elif x == 0:
quit()
else:
print 'false'
play_again()
def play_again():
num = int(raw_input('Input a number: '))
power_of_two(num)
power_of_two(num)
Python程序员可以接受这样的代码,还是有更好的方法来复制我在这里做的事情?
答案 0 :(得分:11)
这种方法的一个问题是你最终会用完堆栈,因为我们有一对相互递归的函数。每次调用都会占用堆栈中的内存,而这些内存永远无法恢复。
这对于交互式程序来说并不明显,因为创建足够的递归调用需要很长时间,但如果我们加快速度:
def power_of_two(x):
print(str(x))
play_again(x)
def play_again(x):
power_of_two(x+1)
power_of_two(1)
我们得到:
RuntimeError: maximum recursion depth exceeded while calling a Python object
有些语言可以进行尾调用优化,所以这种方法运行正常 - 但在Python中最好创建一个循环再次播放&#34;除非你能确定只有是一个小的呼叫深度。
答案 1 :(得分:3)
一般来说,这不是一个非常好的编程方式,因为(除了可能的最大递归深度问题)如果你的程序变得更复杂,你最终会在不同的函数之间跳转多次spaghetti-like ,使其越来越难以阅读和调试。
相反,使用main
函数控制整个程序流并调用其他函数更为标准。在两个函数之间更清晰地分离角色也是更好的。
def power_of_two(x):
y = 1
while y < x:
y *= 2
return y == x
def get_number():
return int(raw_input('Input a number (type 0 to quit): '))
def main():
while True:
n = get_number()
if n == 0:
return
print power_of_two(n)
main()
答案 2 :(得分:2)
不 - 正如已经说过的那样,你有可能遇到堆栈溢出。
你最好做
def power_of_two(x):
y=1
z=[]
while y < x:
y=y*2
z.append(y)
if x in z or x == 1:
print 'true'
elif x == 0:
quit()
else:
print 'false'
def play():
while True:
num = int(raw_input('Input a number (type 0 to quit): '))
power_of_two(num)
这很接近你的解决方案,但远非完美。
最好将功能喷射到它所承诺的范围内:检查数字是否是2的幂,而不是其他任何东西。
def power_of_two(x):
y = 1
z = set((1,)) # as only "in" is performed, a set is better here...
# Having 1 in the set initially saves the extra check for x == 1...
while y < x:
y = y * 2
z.append(y)
return x in z
def play():
while True:
num = int(raw_input('Input a number (type 0 to quit): '))
if num == 0:
return # or just break
else:
print power_of_two(num) # prints "True" or "False"
print 'true' if power_of_two(num) else 'false' # prints "true" or "false"
如果你想使用for循环,你可以用生成器的形式创建一个iterable,它产生值直到不再有:
def numbers():
while True:
num = int(raw_input('Input a number (type 0 to quit): '))
if num == 0:
return # or just break
else:
yield num
def play():
for num in numbers():
# power_of_two() is the same as above.
print power_of_two(num) # prints "True" or "False"
print 'true' if power_of_two(num) else 'false' # prints "true" or "false"
即使这个内部while循环也可以用for循环替换,例如: G。计数:
def numbers():
import itertools
for round in itertools.count(1):
num = int(raw_input('Input number ' + str(round) + ' (type 0 to quit): '))
if num == 0:
return # or just break
else:
yield num