代码传递给一个数组。我的理解是这个传递是通过引用完成的。我希望函数递归地将列表的最后剩余的一半分成两部分,并将它被拆分的每个值设置为零。 零更改发生在数组中,但是当我在最后调用print a时,我得到了原始数组。
我做错了什么?
a = range(10)
def listreduction(array):
if len(array) == 1:
array[0] = 0
return
split = len(array)/2
array[split] = 0
return listreduction(array[split:])
listreduction(a)
print a
当前输出
[0, 1, 2, 3, 4, 0, 6, 7, 8, 9]
第二个的右边应该是更多的零
答案 0 :(得分:2)
切片会创建一个新列表。如果你想以递归方式执行此操作,则必须传递函数应该在列表上工作的索引,而不是实际的切片。
答案 1 :(得分:1)
由于您使用递归,因此参数中的切片操作将创建与您的实例不同的新列表实例。这就是原因。
您可以按以下方式更改代码:
a = range(10)
def list_reduction(array, position=0):
if len(array) -1 <= position:
return
split = position + (len(array) - position) / 2
array[split] = 0
return list_reduction(array, split)
list_reduction(a)
print a
输出结果为:
[0, 1, 2, 3, 4, 0, 6, 0, 0, 0]
答案 2 :(得分:1)
这可能是你想要的。
a = range(1, 10)
def list_reduction(l, prev_split_pos=None):
split_pos = (len(l) + prev_split_pos) / 2 if prev_split_pos else len(l) / 2
if split_pos == prev_split_pos:
return
l[split_pos] = 0
return list_reduction(l, split_pos)
list_reduction(a)
print a
那么,对你的代码。每次执行列表切片时,实际上都会生成一个新列表,该列表与旧列表完全没有关联。这就是为什么除了第一个之外你没有看到任何突变的原因。
答案 3 :(得分:1)
在Python中,argumnet传递与其他传统编程语言不同。参数由对象引用传递。以及是否修改引用的对象取决于两件事
range
将创建一个列表,以便它是一个可变对象。这意味着,如果您更新array
,则还应更新a
。 =
操作将始终创建新的对象引用。所以即使你的情况array
是可变的,但是因为你正在进行赋值操作它将创建一个新的对象引用。 以下示例应该为您清理一些事情。
示例1
>>> a = [1,2]
def fun1(array):
array= array + [3]
print "var array = %s" %array
fun1(a)
print "var a = %s" %a
<强>输出强>
var array = [1, 2, 3]
var a = [1, 2]
示例2
a = [1,2]
def fun1(array):
array.append(3)
print "var array = %s" %array
fun1(a)
print "var a = %s" %a
<强>输出强>
var array = [1, 2, 3]
var a = [1, 2,3]