2016-02-18 3 views
1

У меня есть метод, который не содержит циклов. Я передаю список в этот метод. Поручаю пополнится значение на этом фрагменте кода:Почему я не могу изменить список в методе?

def do_paging(pageable_list): 
    pageable_list = pageable_list[start:end] 

В вызывающем коде:

do_paging(source_list) 

но не выглядеть source_list получает изменилось. Если я вернусь pageable_list от do_paging(), все будет здорово. Являются ли аргументы массива неизменяемыми?

Я начал возвращать значение, потому что это лучше. Но я удивлен и хотел бы знать, что происходит.

EDIT - как я мог программировать Python в течение года и не знал этого!

+1

Аргументы в Python всегда передаются по значению. Вы просто затеняете аргумент, определяя новое имя 'pageable_list'. –

+0

Вы не изменяете список, вы создаете новый список. Чтобы изменить список, вы должны изменить список. Например, 'pageable_list.append (" something ")' будет изменять список. –

+0

Пожалуйста, прочтите следующее: http: // stackoverflow.com/a/986145/2670792 – Christian

ответ

5

нарезка создает новый список:

>>> a = [1,2,3] 
>>> b = a[1:2] 
>>> a is b 
False 

Вы не мутирует первоначальный список:

>>> a 
[1, 2, 3] 

Кроме того, вы никогда не делать что-либо со списком присвоить имя pageable_list в ваша функция do_paging.

Таким образом, проблемы: a) вы не изменяете исходный список и/или b) ничего не возвращаете из своей функции. Один из способов сделать ваш код работать, чтобы создать срез и переназначить имя pageable_list для возвращаемого значения вашей функции, а именно:

def do_paging(pageable_list, start, end): 
    return pageable_list[start:end] 

pageable_list = do_paging(pageable_list, start, end) 

функцию, вероятно, следует принимать start и end аргументов, а также, ищут тех, кто в глобальное пространство отчасти уродливо.

Однако, если все, что вам нужна ваша функция, чтобы сделать это нарезка, функция не очень полезно, вы могли бы просто использовать линию

pageable_list = pageable_list[start:end] 
+0

'start' и' end' находятся в методе. Я опубликовал фрагмент. –

+0

@TonyEnnis в порядке, тогда вам не нужны эти дополнительные аргументы. – timgeb

+3

Я согласен, что для этой задачи метод немного тяжеловес. Тем не менее, существует простой способ изменить список в методе в том, как OP хочет использовать назначение срезов: 'pageable_list [:] = pageable_list [start: end]' –

2

Вы не меняете «список». Вы назначаете новое значение локальной переменной.

мутирование список сам будет работать:

def do_paging(pageable_list): 
    pageable_list.pop() 

Но переменная pageable_list это просто локальная переменная и назначая некоторое новое значение к нему не изменяет значение, которое было ранее присвоенный ему.

3

Я заметил этот метод ниже, когда я недавно был обзор code from Quantopian и никогда раньше не использовалось. В комментарии от @Steven_Rumbalski это назначает срез обратно входной переменной pageable_list.

def do_paging(pageable_list, start, end): 
    pageable_list[:] = pageable_list[start:end] 

a = [1, 2, 3, 4, 5] 

do_paging(a, 2, 4) 

>>> a 
[3, 4] 
+2

Термин, который вы ищете, - это * назначение среза *. Это не имеет никакого отношения к указателям и переменным. Скорее, 'pageable_list [:] = pageable_list [start: end]' является синтаксическим сахаром для вызова метода mutating 'pageable_list .__ setslice__'. –

+1

Действительно, поскольку 'a = 1' и' a [:] = 3' возвращает ошибку 'TypeError: 'int' объект не поддерживает присвоение элемента'. Спасибо за образование. – Alexander

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