Функция, которая изменяет аргумент вне этой функции без использования & ldquo; return & rdquo; python [duplicate]

Если элемент, к которому вы пытаетесь получить доступ, находится внутри iframe, и вы пытаетесь получить к нему доступ за пределами контекста iframe, это также приведет к сбою.

Если вы хотите получить элемент в iframe, вы можете узнать, как здесь .

4
задан Tim 17 July 2013 в 10:22
поделиться

6 ответов

Переменные Python содержат указатели или ссылки на объекты. Все значения (даже целые) являются объектами, а присваивание изменяет переменную на другой объект. Он не сохраняет новое значение в переменной , он изменяет переменную для ссылки или указывает на другой объект. По этой причине многие люди говорят, что у Python нет «переменных», у него есть «имена», а операция = не «присваивает значение переменной», а скорее «связывает имя с объектом». "

В plusOne вы изменяете (или« мутируете ») содержимое в y, но никогда не меняете то, что относится к самому y. Он остается указывать на тот же список, который вы передали функции. Глобальная переменная y и локальная переменная y относятся к одному и тому же списку, поэтому изменения видны с использованием любой переменной. Поскольку вы изменили содержимое объекта, который был передан, на самом деле нет причин возвращать y (фактически, возвращение None - это то, что сам Python делает для таких операций, которые изменяют список «на месте» - значения возвращаются операциями, которые создают новые объекты, а не мутируют существующие).

В plusOne2 вы меняете локальную переменную a, чтобы ссылаться на другой целочисленный объект, 3. («Связывание имени a с объектом 3.») Глобальная переменная a не изменяется этим и продолжает указывать на 2.

Если вы не хотите изменить список, пройденный, сделать копию и изменить его. Затем ваша функция должна возвращать новый список, так как это одна из тех операций, которая создает новый объект, и новый объект будет потерян, если вы его не вернете. Вы можете сделать это как первую строку функции: x = x[:], например (как указывали другие). Или, если было бы полезно, чтобы функция называлась в любом случае, вы можете иметь вызывающего абонента в x[:], если он хочет сделать копию.

11
ответ дан kindall 19 August 2018 в 02:44
поделиться
  • 1
    Это немного запутанно для новичков (потому что никто не изучает программирование через Python, не знает, что такое указатель) и вводит в заблуждение для кого-либо еще (поскольку переменные не являются указателями, они являются именами, а проблема связана с привязкой к мутации, а не с указательными переменными против обычных переменных). – abarnert 16 July 2013 в 21:51
  • 2
    Я сделал некоторые изменения, чтобы прояснить некоторые из них. Я надеюсь. – kindall 16 July 2013 в 22:37

Чтобы ответить на ваш отредактированный вопрос:

Копирование вложенных структур данных называется глубоким копированием . Для этого в Python используйте deepcopy() в модуле copy .

2
ответ дан John Y 19 August 2018 в 02:44
поделиться

Просто создайте новый список со значениями, которые вы хотите в нем, и верните их вместо этого.

def plus_one(sequence):
    return [el + 1 for el in sequence]
3
ответ дан Jon Clements 19 August 2018 в 02:44
поделиться

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

print plusOne(y[:]), y

Или лучшим способом было бы создать копию списка в самой функции, чтобы вызывающий должны беспокоиться о возможной модификации:

def plusOne(y):
    y_copy = y[:]

и работать с y_copy.


Или, как указано в комментариях @abarnet, вы можете изменить чтобы использовать list comprehension, который создаст новый список:

return [x + 1 for x in y]
4
ответ дан Rohit Jain 19 August 2018 в 02:44
поделиться
  • 1
    Или, что еще лучше, перепишите код, чтобы он копировал копию на лету: y = [x+1 for x in y]. – abarnert 16 July 2013 в 21:49
  • 2
    @abarnert. Правильно :) спасибо, отредактировал ответ. :) – Rohit Jain 16 July 2013 в 21:51

Как указывали другие, вы должны использовать newlist = original[:] или newlist = list(original) для копирования списка, если вы не хотите изменять оригинал.

def plusOne(y):
    y2 = list(y)  # copy the list over, y2 = y[:] also works
    for i, _ in enumerate(y2):
        y2[i] += 1
    return y2

Однако вы можете добиться желаемого вывод с пониманием списка

def plusOne(y):
    return [i+1 for i in y]

Это приведет к переходу по значениям в y и созданию нового списка, добавив один к каждому из них

1
ответ дан Ryan Haining 19 August 2018 в 02:44
поделиться

Создайте копию списка. Используя testList = inputList[:]. См. Код

>>> def plusOne(y):
        newY = y[:]
        for x in range(len(newY)):
            newY[x] += 1
        return newY

>>> y = [1, 2, 3]
>>> print plusOne(y), y
[2, 3, 4] [1, 2, 3]

Или вы можете создать новый список в функции

>>> def plusOne(y):
        newList = []
        for elem in y:
            newList.append(elem+1)
        return newList

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

>>> def plusOne(y):
        return [elem+1 for elem in y]
6
ответ дан Sukrit Kalra 19 August 2018 в 02:44
поделиться
  • 1
    Вау, спасибо за быстрые ответы !! Я пробовал newY = y, и это не сработало, а должно было быть просто newY = y [:]. – Tim 16 July 2013 в 21:52
  • 2
    newY = y просто создает для него другую ссылку, а newY = y[:] создает новый список. – Sukrit Kalra 16 July 2013 в 21:55
  • 3
    Да, теперь я понимаю, и все становится ясно! Благодаря! – Tim 17 July 2013 в 06:16
Другие вопросы по тегам:

Похожие вопросы: