作者:鬼王守护灵 | 来源:互联网 | 2022-11-29 11:44
是的,您可以在函数中更改列表,但需要使用正确的语法.正如您已经看到的那样,这不是正确的方法:
def leftRotate(arr, k, n):
arr = arr[k:] + arr[:k]
我将尝试解释为什么这不起作用,并希望能让你对真正发生的事情有更好的直觉.内部上面示出的功能的范围内,有3个局部变量:arr
,k
,和n
.右侧操作arr[k:] + arr[:k]
创建一个新的列表对象,而不修改原始列表,并且此结果对象绑定到本地变量名称 arr
.这不会修改原始对象,因为Python中的这些赋值语句永远不会改变对象.它们只会绑定名称空间中的名称.可以把它想象成你从旧列表对象中获取名称"arr",它是作为参数传递的,并将它粘贴在刚刚创建的新列表对象上.旧的列表对象不会被这样的操作修改,只修改本地命名空间 - 旧的列表对象变为"匿名",并且在此范围内不再可访问.
解决方案是使用不同类型的赋值语句,即切片赋值,它会变异:
def leftRotate(arr, k, n):
arr[:] = arr[k:] + arr[:k]
最后需要注意的是,stdlib中有一个类似列表的数据结构,它提供了更高效的循环操作(代价是在集合中间的索引效率较低).如果您对此感兴趣,请阅读文档collections.deque
.
1> wim..:
是的,您可以在函数中更改列表,但需要使用正确的语法.正如您已经看到的那样,这不是正确的方法:
def leftRotate(arr, k, n):
arr = arr[k:] + arr[:k]
我将尝试解释为什么这不起作用,并希望能让你对真正发生的事情有更好的直觉.内部上面示出的功能的范围内,有3个局部变量:arr
,k
,和n
.右侧操作arr[k:] + arr[:k]
创建一个新的列表对象,而不修改原始列表,并且此结果对象绑定到本地变量名称 arr
.这不会修改原始对象,因为Python中的这些赋值语句永远不会改变对象.它们只会绑定名称空间中的名称.可以把它想象成你从旧列表对象中获取名称"arr",它是作为参数传递的,并将它粘贴在刚刚创建的新列表对象上.旧的列表对象不会被这样的操作修改,只修改本地命名空间 - 旧的列表对象变为"匿名",并且在此范围内不再可访问.
解决方案是使用不同类型的赋值语句,即切片赋值,它会变异:
def leftRotate(arr, k, n):
arr[:] = arr[k:] + arr[:k]
最后需要注意的是,stdlib中有一个类似列表的数据结构,它提供了更高效的循环操作(代价是在集合中间的索引效率较低).如果您对此感兴趣,请阅读文档collections.deque
.