2013-09-28 3 views
-1

Я хотел иметь хорошую функцию set all list elements to a default value. Тот, с которым я пришел, не работает, но мое второе решение. Может ли кто-нибудь сказать мне, почему это работает в одном направлении, но не в другом?Почему я не могу изменить списки таким образом?

Первое решение:

def set_all(the_list,value): #NOT doing anything 
    for item in the_list: 
     item = value 

Второе решение:

def set_all(the_list,value): #working as intended 
    for i,item in enumerate(the_list): 
     the_list[i] = value 
+0

См. http://stackoverflow.com/q/575196/395760 - Я не думаю, что это точный дубликат, но это, безусловно, очень связано. – delnan

ответ

5

Когда вы делаете:

for item in the_list: 
    item = value 

Вы только повторно назначая имяitem на что-то другое (value, specifici cally), но вы не трогаете ссылкуthe_list[i], что список принадлежит оригинальному изделию.

Следовательно, вы фактически не прикасаетесь к списку, поэтому он не изменяется.


Вы можете посмотреть на это так:

Когда вы for item in the_list, вы создаете новую ссылку на базовый объект: item.

Когда вы делаете item = value, вы меняете эту ссылку и указываете ее на что-то еще. Но другая ссылка, та, которая имеет список для основного объекта, остается неизменной.

Конечно, когда вы делаете the_list[i], вы фактически меняете эту ссылку, которую имеет список для объекта, поэтому он работает.

+0

Итак, когда я повторяю, 'item' является копией' the_list [x] '? Поэтому полезно только для чтения данных, не меняя/записывая их? – Wurstbro

+0

@Wurstbro Нет, это не копия. В Python нет правильных переменных. Есть только имена, указывающие на базовые объекты. Когда вы выполняете 'item.some_method()', вы можете изменить объект (например, если 'item' был' list' и вы вызвали 'append'), и все имена, указывающие на этот объект, будут видеть объект, который имеет был изменен. Однако, когда вы ** изменяете имя **, переназначая его, вы не изменяете базовый объект и другие ссылки, которые существуют для него. –

+0

Могу ли я сказать, что 'item' указал на' the_list [x] ', а затем указывает на' значение'? – Wurstbro

2

В первом цикле item является ссылкой на элемент из списка, а не слотом в списке. Изменение этого не меняет список.

Чтобы изменить список, вам нужно знать, в каком слоте вы имеете дело, что вы делаете во втором случае.

0

Почему бы не использовать это? его легче

the_list = [default_value]*len(the_list) 
+0

Ну, это не мутирует список, а создает новый, что важно, если есть другие ссылки. Но в любом случае это был не вопрос, а вопрос только: «Почему первый не работает (а второй делает)»? – delnan

+0

Мне нужен был способ изменить все значения в существующих списках – Wurstbro

+0

Да, имеет смысл, я думал, что если вы не возражаете сделать новый, это было бы более чистым решением. –

Смежные вопросы