切片列表而不复制

时间:2015-07-07 16:52:06

标签: python list slice

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

这是非常相关的,但是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返回已更改列表并在调用工作区中分配的唯一方法吗?

3 个答案:

答案 0 :(得分:4)

如果您只想修改列表的一部分,则只能发送该切片,并使用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])

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

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

答案 1 :(得分:0)

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]

答案 2 :(得分:0)

为了提供替代方案,这仅适用于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]

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