切片列表而不复制

Slicing a list without copying

这是我在论坛上的第一个问题,我也是 Python 的新手,所以这可能没有多大意义,但我只是想知道...

非常相关,但 IMO 这个问题 Slicing a list in Python without generating a copy 没有回答如何以更改切片会更改原始列表的方式对列表进行切片的问题?

比如说,如果我只想更改函数中列表的一部分,并确保该函数无法访问所有成员,我该如何编写:

def myFunc(aList):
    for i in range(0,len(aList)):
        aList[i] = 0

wholeList = range(0,10)
partOfList = wholeList[3:6]
myFunc(partOfList)

所以最后 wholeList 会是

[0, 1, 2, 0, 0, 0, 6, 7, 8, 9] 

??

我想如果 wholeList 的内容是可变对象,这会起作用,但是使用数字是让 myFunc return 更改列表并在调用工作区?

如果您只想修改列表的一部分,您可以只发送该部分,然后使用 return:

将修改分配给同一部分
def myFunc(aList):
    for i in range(0,len(aList)):
        aList[i] = 0
    return aList

wholeList = range(0,10)
wholeList[3:6] = myFunc(wholeList[3:6])

否则,正如您之前所说,您只是在创建新列表,而这些新列表恰好引用了原始切片中包含的内容,您必须将对新列表的任何修改重新分配回旧列表。

为了进一步说明,wholeList[3:6]partOfList 元素 是相同的 对象 。但列表只是对这些对象的引用。所以 id(wholeList[3]) == id(partOfList[0]),但是如果我们更改其中一个引用,例如 partOfList[0] = 10,那么我们将 partOfList[0]reference 更改为 10不是指向的实际 object (3)。因此,此修改中没有任何操作会反映 wholeList 中的任何更改,因为它仍然引用原始对象..

You can modify the list directly:
>>> wholeList = range(0,10)
>>> wholeList[3:6] = [0 for _ in range(3)] # or = [0]*3
>>> wholeList
[0, 1, 2, 0, 0, 0, 6, 7, 8, 9]

要提供替代方案,这仅适用于 Python 2:

In [2]: a = range(10)
In [3]: a.__setslice__(3,6,[0]*3)

In [4]: a
Out[4]: [0, 1, 2, 0, 0, 0, 6, 7, 8, 9]

但是,我会投票支持其他人提供的解决方案,因为它们更具可读性。 :))