为什么变量在循环外表现不同?

0 投票
3 回答
1795 浏览
提问于 2025-04-18 18:21

如果我运行这段代码:

def numbers_in_lists(string):
    next_number = 0
    count = 0
    final_list = []
    while count < len(string):
        number = int(string[count])
        if number > next_number:
            final_list.append(number)
            new = []
            next_number = number
        else:
            new.append(number)
            if new not in final_list:
                final_list.append(new)
        count += 1
    print final_list


#testcases
string = '543987'
result = [5,[4,3],9,[8,7]]
print repr(string), numbers_in_lists(string) == result

我得到这个结果:

'543987' [5, [4, 3], 9, [8, 7]]
False

但是如果我把 number 变量放在 while 循环外面,像这样:

def numbers_in_lists(string):
    next_number = 0
    count = 0
    final_list = []
    number = int(string[count])
    while count < len(string):
        if number > next_number:
            final_list.append(number)
            new = []
            next_number = number
        else:
            new.append(number)
            if new not in final_list:
                final_list.append(new)
        count += 1
    print final_list

我得到这个结果:

'543987' [5, [5, 5, 5, 5, 5]]
False

我还是个初学者,四处寻找为什么 number 变量在循环外面表现得不一样的解释?还有,为什么其他变量在循环外面没问题,而 number 变量却不行呢?

任何帮助都非常感谢。谢谢你。 :)

3 个回答

1

这段代码 number = int(string[count]) 使用的是在循环外面给 count 赋的值,这个值是第一个字符,也就是 index 0 的位置。因为这个值在循环外面不会改变,所以每次你得到的都是原来的值,也就是第一个字符。

而如果你在循环里面使用 number = int(string[count]),那么每次循环的时候,number 都会被重新赋值为 index count 位置的元素,这样每次你得到的都是输入字符串的不同部分。

一旦你进入了 while loop,在循环外面定义的任何值如果被改变了,循环外面的值是不会受到影响的。你必须在循环里面重新赋值。

1

我知道你是个初学者。下面是一些有用的Python写法和构造的改写,希望能帮到你:

def numbers_in_lists(string):
    numbers = [int(c) for c in string]
    next_number = -1
    final_list = []
    for number in numbers:
        if number > next_number:
            final_list.append(number)
            final_list.append([])
            next_number = number
        else:
            final_list[-1].append(number)
    final_list = [x for x in final_list if x != []]
    print final_list

首先,当你看到有一个while循环和一个计数器时,要保持警惕。你可以用一个for循环来遍历所有的项目,这样更简单。

因为这段代码处理的是整数,而不是字符串中的字符,所以我们可以用列表推导式一次性把它们都转换过来:

numbers = [int(c) for c in string]

这样就创建了一个列表,里面的所有字符都被转换成了整数。

通过设置next_number = -1,我们确保numbers中的所有数字都会大于这个值。特别是,第一个元素一定会大于它。

当我们找到一个number,它比我们上一个最大值next_number还要大时,我们就把这个number和一个桶放进去,用来装后面小于这个number的数字:

        if number > next_number:
            final_list.append(number)
            final_list.append([])
            next_number = number

这意味着当我们添加5时,final_list看起来是这样的:

[5, []]

而当number43时,它们也会被正确地添加进去:

[5, [4]]
[5, [4, 3]]

这是怎么做到的呢?这段代码实现了这一点:

        else:
            final_list[-1].append(number)

在这里,我们不是直接添加到final_list,而是添加到final_list中的最后一个列表,也就是final_list[-1]

但是如果我们的序列只有5呢?那么在循环结束时,final_list会是这样的:

[5, []]

在这种情况下,我们想要去掉所有空列表,所以我们可以这样做:

final_list = [x for x in final_list if x != []]

这段代码的意思是:“把final_list变成一个新的列表,里面包含final_list中的所有元素,除了那些空列表。”

祝你学习Python顺利,希望你能从中获得乐趣。

1

你把 number 声明为

number = int(string[count])

所以当

count = 0

这意味着 number 将会是你字符串的第一个字符(位置 [0])转换成 int 类型。如果你在循环中不更新 number,它就永远不会改变。在你代码的第一版中,number 是在你的 while 循环里面的。

while count < len(string):
    number = int(string[count])
    # more code
    count += 1

注意在循环结束时,你会增加 count 的值。这意味着在下一次循环开始时,count 的值会增加,所以 number 会变成你字符串中的下一个字符的值。

初学者常常有一个误解,就是认为一个变量会“绑定”到另一个变量上。例如:

>>> a = 5
>>> b = a
>>> b
5

>>> a = 7
>>> b
5

看,即使 a 的值从 5 变成了 7b 的值并不会改变,因为它并没有以任何方式“绑定”到 a。这一行 b = a 的意思是“把 a 的值取出来,赋值给 b”,之后 b 就不再关心 a 发生了什么。

撰写回答