问题
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