Python:帮助,功能不能产生我想要的东西

时间:2017-01-13 12:55:56

标签: python algorithm loops

我试图制作一个连续打印数字的连续标记序列,因为我输入的是初始整数,直到它达到1但它的效果不好。

def collatz():
    try:
        number = int(input("Please enter a number: "))
    except ValueError:
        collatz()
    while number != 1:
        if number%2 == 0:
            print(number // 2)
        else:
            print(3 * number + 1)

这是我创建的,它只返回单个计算的值

>>> collatz()
Please enter a number: 45
136
>>> collatz()
Please enter a number: 8
4

我不太明白为什么会发生这种情况,因为我希望计算继续进行并保持打印值直到达到1(它总是会达到1,这就是序列的诀窍)

6 个答案:

答案 0 :(得分:3)

您永远不会将任何新值分配给number,因此while循环永远为True。

计算新值,将其分配回number,然后打印新值:

while number != 1:
    if number % 2 == 0:
        number //= 2
    else:
        number = 3 * number + 1
    print(number)

请注意,不应使用递归来获取有效输入;请改用while循环。在您的情况下,当递归函数退出并返回时,代码将继续while循环,number未绑定,导致UnboundLocal异常。

我要求在函数外面 这个号码,也许是在一个新函数中:

def collatz(number):
    while number != 1:
        if number % 2 == 0:
            number //= 2
        else:
            number = 3 * number + 1
        print(number)

def ask_for_number():
    while True:
        try:
            return int(input("Please enter a number: "))
        except ValueError:
            print("That's not a valid number, please try again")

collatz(ask_for_number())

现在,您可以轻松地测试collatz()功能,而无需向用户索取号码:

>>> collatz(45)
136
68
34
17
52
26
13
40
20
10
5
16
8
4
2
1

答案 1 :(得分:2)

if number%2 == 0:
    print(number // 2)
else:
    print(3 * number + 1)

您实际上并没有更改数字的值:

if number%2 == 0:
    print(number // 2)
    number = number // 2
else:
    print(3 * number + 1)
    number = 3 * number + 1

答案 2 :(得分:2)

这是你之后的事吗?

def collatz(starting_value):
    value = starting_value

    while value != 1:
        value = (3 * value + 1) if value % 2 else (value // 2)
        yield value

if __name__ == '__main__':
    start = int(input("Please enter starting value: "))
    print(list(collatz(start)))

运行示例

Please enter starting value: 136
[68, 34, 17, 52, 26, 13, 40, 20, 10, 5, 16, 8, 4, 2, 1]

如何运作

这段代码依赖于所谓的generator functions的使用 - 本质上,它看起来像一个函数但行为类似于迭代器。 collatz是生成器函数,在每次迭代时,它将生成Collat​​z序列中的下一个术语。

当我们直接执行包含此代码的模块时,Python解释器会将其__name__变量设置为'__main__',使得底部的if语句为真。

在if块中,我们提示用户输入值以开始Collat​​z序列。我们假设它们输入了一个有效数字(其他任何东西都会导致抛出未处理的异常)。

表达式collatz(start)将生成生成器对象,我们可以迭代。我们将这个对象直接传递给list,它会一直要求对象反复产生下一次迭代,直到它耗尽为止。我们真的希望Collat​​z'猜想是正确的,否则这个程序可能会永远运行!

在Collat​​z'虽然猜想似乎确实存在,但最终while条件value != 1变为false,这意味着生成器对象停止生成值。此时,它会引发StopIteration以表示它没有更多值,list将返回我们随后打印的完整Collat​​z条款列表。

yield中的collatz语句与return的行为类似,只是主叫线程会记住&{39}。它的位置 - 当我们要求序列中的下一个术语时,它将从该点开始,使用函数的局部变量的最后存储值(即value)。

垂直打印

如果您想要垂直打印这些术语,您可以在for循环中迭代生成器,并在新行上打印它产生的每个术语:

if __name__ == '__main__':
    start = int(input("Please enter starting value: "))
    for term in collatz(start):
        print(term)

<强>输出

Please enter starting value: 136
68
34
17
52
26
13
40
20
10
5
16
8
4
2
1

答案 3 :(得分:0)

您忘了更新module: { loaders: [ { test: /\.js$/, exclude: /node_modules/, loader: 'babel-loader?presets[]=es2015&presets[]=react' } ] } 试试这个:

number

我希望它会有所帮助。

答案 4 :(得分:0)

def collatz():
    try:
        number = int(input("Please enter a number: "))
    except ValueError:
        collatz()
    while number != 1:
        if number %2 ==0:
            number = number // 2
        else:
            number = 3 * number + 1
        print(number) 

打印未设置数字的实际值!

答案 5 :(得分:0)

几个问题:

主要一个:您永远不会更改number的值。 因此,您的代码应该反复打印相同的数字。

您也可以查看非正数。

但是当这个问题得到解决时,我会怀疑你遇到的ValueError会遇到一些不必要的行为。 您再次调用相同的功能。完成第二次运行后,代码仍将尝试运行下一行并失败。

实施例:

>>> collatz()
Please enter a number: "foo"
Please enter a number: 4
2
1
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
File "<stdin>", line 6, in collatz
UnboundLocalError: local variable 'number' referenced before assignment

我尝试解决所有问题:

def collatz():
    number = 0
    while number < 1:
        try:
            number = int(input("Please enter a number: "))
        except ValueError, NameError:
            pass

    while number != 1:
        if number%2 == 0:
            number = number // 2
        else:
            number = 3 * number + 1
        print(number)