Slicing a list without copying

狂风中的少年 提交于 2021-02-07 19:18:52

问题


This is my first question on the forum and I'm also really new to Python, so maybe this doesn't make a lot of sense, but I'm just left wondering...

It's very related, but IMO this question Slicing a list in Python without generating a copy does not answer the question of how to slice a list in such a fashion that changing the slice would change the original?

Say, if I want to change only part of a list in a function and make sure that the function doesn't have access to all the members, how do I write this:

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

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

so that the in the end wholeList would be

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

??

I guess this would work if the contents of wholeList were mutable objects, but with numbers is the only way to have the myFunc return the changed list and assign in the calling workspace?


回答1:


If you want to modify just a part of the list, you can send in only that slice, and assign the modifications to that same section using 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])

Otherwise as you said before, you are just creating new lists that happen to reference what is contained in the slice of the original, you'll have to reassign any modifications to the new list back into the old one.

To further clarify, the elements of wholeList[3:6] and partOfList are the same objects. But the lists are just references to those objects. So id(wholeList[3]) == id(partOfList[0]), but if we change one of those references, eg partOfList[0] = 10, then we change the reference of partOfList[0] to 10 not the actual object (3) that was being pointed to. Thus there is no action in this modification that would reflect any changes in wholeList, since it is still referencing the original object..




回答2:


To offer an alternative, this works only in 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]

However, I'd vote for the solutions other people gave because they are more readable. :))




回答3:


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]


来源:https://stackoverflow.com/questions/31274784/slicing-a-list-without-copying

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!