为什么计数器变量在同一个函数中重置为旧值?
why does the counter variable reset to old value within the same function?
我正在尝试获取嵌套列表中所有项目的计数。当代码遍历所有项目时,计数器仅设置为非嵌套列表项目。发生了什么以及如何更正此代码?
def countarr(arr,count):
if len(arr) == 0:
return count
else:
if type(arr[0]) != list:
count += 1
print(arr[0],count)
else:
print ("inner")
countarr(arr[0],count)
return countarr(arr[1:],count)
count=0
arr=[1,2,[[4,5]],8,[7,4,5,6],12,34]
print("Answer: ",countarr(arr, count))
变量不会神奇地重置。它们只被设置为你给它的值。修改局部变量的值不会影响另一个函数中另一个变量的值,即使它具有相同的名称。举个例子:
def foo(count):
print(count)
count += 1
print(count)
def bar()
count = 0
print(count)
foo(count)
print(count)
bar()
递归也是一样。每个递归函数调用都有自己的局部变量副本,就像 foo()
和 bar()
每个都有一个名为 count 的变量,它们彼此独立。
要修复递归函数,只需 return 来自每个可能的 if...else
分支的 count
的值。您已经在其中两个分支中执行了此操作,但您只打印了其他两个分支中的值而没有 return 它。
count
是 int
类型的变量。将 int
作为参数传递给 python 中的函数时,仅传递值,而不传递实际变量。所以,当递归调用“修改count
”时,它实际上修改了变量的副本,而不是原来的。所以,原文没有更新。
此外,当您执行递归调用时:countarr(arr[0])
,您没有使用该调用的 return 值。您可以简单地在递归调用前面添加 count =
,以检索递归调用的 returned 值:
def countarr0(arr,count):
if len(arr) == 0:
return count
else:
if not isinstance(arr[0], list):
count += 1
else:
count = countarr0(arr[0], count)
return countarr0(arr[1:], count)
arr=[1,2,[[4,5]],8,[7,4,5,6],12,34]
print("Answer: ",countarr0(arr, 0))
# Answer: 11
但是,将参数 count
传递给递归调用并不是很有用。递归调用不需要知道 count
的当前值。递归调用应该只计算嵌套子列表中有多少元素,我们将把它的 return 值添加到我们当前的计数中:
def countarr1(arr):
if len(arr) == 0:
return 0
else:
count = 0
if isinstance(arr[0], list):
count += countarr1(arr[0])
else:
count += 1
count += countarr1(arr[1:])
return count
arr=[1,2,[[4,5]],8,[7,4,5,6],12,34]
print("Answer: ",countarr1(arr))
# Answer: 11
请注意,使用递归来导航子列表是个好主意;但是在 python 中使用递归来迭代列表是一个坏主意。在 python 中,递归比 for
循环慢得多;此外,当您编写 arr[1:]
时,会创建一个全新的数组副本!那是非常低效的。相反,我们可以使用循环来迭代列表:
def countarr2(arr):
count = 0
for x in arr:
if isinstance(x, list):
count += countarr2(x)
else:
count += 1
return count
arr=[1,2,[[4,5]],8,[7,4,5,6],12,34]
print("Answer: ",countarr2(arr))
# Answer: 11
我正在尝试获取嵌套列表中所有项目的计数。当代码遍历所有项目时,计数器仅设置为非嵌套列表项目。发生了什么以及如何更正此代码?
def countarr(arr,count):
if len(arr) == 0:
return count
else:
if type(arr[0]) != list:
count += 1
print(arr[0],count)
else:
print ("inner")
countarr(arr[0],count)
return countarr(arr[1:],count)
count=0
arr=[1,2,[[4,5]],8,[7,4,5,6],12,34]
print("Answer: ",countarr(arr, count))
变量不会神奇地重置。它们只被设置为你给它的值。修改局部变量的值不会影响另一个函数中另一个变量的值,即使它具有相同的名称。举个例子:
def foo(count):
print(count)
count += 1
print(count)
def bar()
count = 0
print(count)
foo(count)
print(count)
bar()
递归也是一样。每个递归函数调用都有自己的局部变量副本,就像 foo()
和 bar()
每个都有一个名为 count 的变量,它们彼此独立。
要修复递归函数,只需 return 来自每个可能的 if...else
分支的 count
的值。您已经在其中两个分支中执行了此操作,但您只打印了其他两个分支中的值而没有 return 它。
count
是 int
类型的变量。将 int
作为参数传递给 python 中的函数时,仅传递值,而不传递实际变量。所以,当递归调用“修改count
”时,它实际上修改了变量的副本,而不是原来的。所以,原文没有更新。
此外,当您执行递归调用时:countarr(arr[0])
,您没有使用该调用的 return 值。您可以简单地在递归调用前面添加 count =
,以检索递归调用的 returned 值:
def countarr0(arr,count):
if len(arr) == 0:
return count
else:
if not isinstance(arr[0], list):
count += 1
else:
count = countarr0(arr[0], count)
return countarr0(arr[1:], count)
arr=[1,2,[[4,5]],8,[7,4,5,6],12,34]
print("Answer: ",countarr0(arr, 0))
# Answer: 11
但是,将参数 count
传递给递归调用并不是很有用。递归调用不需要知道 count
的当前值。递归调用应该只计算嵌套子列表中有多少元素,我们将把它的 return 值添加到我们当前的计数中:
def countarr1(arr):
if len(arr) == 0:
return 0
else:
count = 0
if isinstance(arr[0], list):
count += countarr1(arr[0])
else:
count += 1
count += countarr1(arr[1:])
return count
arr=[1,2,[[4,5]],8,[7,4,5,6],12,34]
print("Answer: ",countarr1(arr))
# Answer: 11
请注意,使用递归来导航子列表是个好主意;但是在 python 中使用递归来迭代列表是一个坏主意。在 python 中,递归比 for
循环慢得多;此外,当您编写 arr[1:]
时,会创建一个全新的数组副本!那是非常低效的。相反,我们可以使用循环来迭代列表:
def countarr2(arr):
count = 0
for x in arr:
if isinstance(x, list):
count += countarr2(x)
else:
count += 1
return count
arr=[1,2,[[4,5]],8,[7,4,5,6],12,34]
print("Answer: ",countarr2(arr))
# Answer: 11