为什么变量在循环外表现不同?
如果我运行这段代码:
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 个回答
这段代码 number = int(string[count])
使用的是在循环外面给 count
赋的值,这个值是第一个字符,也就是 index 0
的位置。因为这个值在循环外面不会改变,所以每次你得到的都是原来的值,也就是第一个字符。
而如果你在循环里面使用 number = int(string[count])
,那么每次循环的时候,number
都会被重新赋值为 index count
位置的元素,这样每次你得到的都是输入字符串的不同部分。
一旦你进入了 while loop
,在循环外面定义的任何值如果被改变了,循环外面的值是不会受到影响的。你必须在循环里面重新赋值。
我知道你是个初学者。下面是一些有用的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, []]
而当number
是4
和3
时,它们也会被正确地添加进去:
[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顺利,希望你能从中获得乐趣。
你把 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
变成了 7
,b
的值并不会改变,因为它并没有以任何方式“绑定”到 a
。这一行 b = a
的意思是“把 a
的值取出来,赋值给 b
”,之后 b
就不再关心 a
发生了什么。