2015-07-07 18 views
4

Это мой первый вопрос на форуме, и я тоже очень новичок в 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 сменившийся список и назначить в рабочей области?

ответ

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]) 

В противном случае, как вы сказали ранее, вы просто создавая новые списки, которые ссылаются на то, что содержится в фрагменте оригинала, вам придется переназначить любые изменения в новом списке обратно в старый.

В целях дальнейшего уточнения, то элементы из wholeList[3:6] и partOfList одни и те же объекты . Но списки - это просто ссылки на эти объекты. Так id(wholeList[3]) == id(partOfList[0]), но если мы изменим одну из этих ссылок, например partOfList[0] = 10, то мы изменим ссылку из partOfList[0] в 10 не фактический объект (3), который в настоящее время указал. Таким образом, нет никаких действий в этой модификации, которая будет отражать любые изменения в wholeList, так как он по-прежнему ссылается на исходный объект ..

+0

Спасибо за разъяснение. Эта концепция списка, содержащая только ссылки на реальные объекты, более или менее понятна мне ... Я думаю, что я действительно пытался спросить, можно ли создать 'partOfList', который будет содержать те же ссылки, что и' wholeList ', но не все из них. Таким образом, можно изменять только часть 'wholeList' без явного назначения. Я предполагаю, что короткий ответ - «нет». – Juspe

+0

@ Juspe Правильно, это просто списки ссылок, изменение одного элемента списка не будет отражать ни в каких других списках **, пока эти объекты неизменяемы **. Если они являются изменяемыми объектами, то их можно изменить «через срез» для каждого. – Jkdc

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

Пожалуйста, добавьте краткое описание кода, чтобы сделать его лучшим. – Thalia

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] 

Тем не менее, я проголосовал за решения, которые другие люди дали, потому что они более читабельны. :))