Leetcode Remove Element

利用Python的list comprehension想写出一行代码

class Solution:
    # @param {integer[]} nums
    # @param {integer} val
    # @return {integer}
    
    def removeElement(self, nums, val):
        # nums = [x for x in nums if x!=val]
        z = [y for y in nums if y != val]
        for k,v in enumerate(z):
            nums[k] = v
        return len(z)

但是题目要求要在原地修改list的内容,所以原来就想着直接给nums赋值,结果大错特错!

问题在于,Python中的Naming是将一个名字和一个Object绑定即binding,而不是以前的assign。带图的解释戳这里

而且Python的binding是有作用域的,即scope。在一个作用域里的绑定是不会在子作用域里被改变的。

在这里就是,大环境下绑定了nums(原),而在函数中重新建立了一个list并用nums(新)去绑定了。当函数执行完毕之后,回到大环境下,nums其实还是nums(原),所以之前的写法会错。

这一段论述可以由下图验证:

 

那这样的解决办法就是在函数中,给nums(原)绑定的对重写。即for k,v in enumerate(z): nums[k] = v。