Локальные и глобальные списки в Python - PullRequest
0 голосов
/ 12 февраля 2019

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

def mystery(list1):
  list1[0] , list1[1] = list1[1], list1[0]

list1 = [7,82,44,23,11]
mystery(list1)
print(list1) #prints [82, 7, 44, 23, 11]

, как оно может изменить значение глобального list1, если я изменю свою функциюна

def mystery(list1):
  list1 = list1 + list1[2:5]

тогда я получаю глобальное значение list1, а не обновленное.

Ответы [ 5 ]

0 голосов
/ 12 февраля 2019

Передача изменяемых объектов в функцию, а затем изменение объекта внутри функции будет иметь тот же эффект, что и непосредственное изменение объекта.

list1 = [1,2,3]

def func(list1):
    list1[0] = 5

>>>list1
[5,2,3]

Это фактически то же самое, что и прямой запуск list1[0] = 5

Однако, если вы передадите неизменный объект в функцию, такую ​​как кортеж, он не будет поддерживать назначение элемента TypeError: 'tuple' object does not support item assignment.Поэтому вам нужно построить новый неизменный объект и вернуть его.

>>> tup1 = (1,2,3) # doing tup1[0] = 5 will cause TypeError
>>> tup2 = tup1 + (5,)
>>> tup2
(1, 2, 3, 5)

Включите его,

>>> def func2(tup1):
        return tup1 + (5,)

>>> func2(tup1=(1,2,3))
(1, 2, 3, 5)
0 голосов
/ 12 февраля 2019

В Python присвоение значения такой переменной, как a = 5, означает, что вы создаете объект в памяти для значения 5. Теперь a - это ссылка на этот объект, содержащий 5 (в терминах Layman).Если вы измените a сейчас, скажем a = "something else", это создаст новый объект для строки "something else" в другом месте в памяти, и теперь a указывает на это.Вот почему вы можете изменить тип данных переменных Python.

Когда вы передаете что-то в функцию Python, передается эта ссылка.Поэтому, когда вы звоните mystery(list1), передается оригинальная ссылка на list1.Поэтому изменение элемента в list1 означает, что вы назначаете новое значение этому конкретному элементу в исходном list1.Независимо от того, находитесь ли вы внутри или вне функции mystery(), в этом случае вы будете использовать исходную ссылку, созданную вами, для доступа к элементу внутри list1, чтобы изменить его.Изменение происходит внутри list1;list1 не был переназначен.

Однако, когда вы делаете list1 = "something new" внутри своей функции mystery(), вы создаете новую переменную list1 внутри функции, которая является локальной для этой функции.Вы не меняете оригинал list1.

0 голосов
/ 12 февраля 2019

Может, просто вернуть список?

def mystery(list1):
    return list1 + list1[2:5]

list1 = [7,82,44,23,11]
list1 = mystery(list1)
print(list1)
0 голосов
/ 12 февраля 2019

Причина, по которой list1 меняется, заключается в том, что вы на самом деле модифицируете объект списка внутри функции.

Это действительно не имеет ничего общего с глобальными / локальными переменными, если вы переименовали параметр внутри вашей функции в нечтоиначе, и все еще передается в list1, list1 будет изменен.

Если вы хотите вернуть новый список, вам нужно сначала создать копию списка, есть много способов сделать это.list(list1) это один из способов.Затем return список в конце функции.

Если я понимаю ваш квест, вы хотите добавить еще несколько значений к переданному списку, используйте list1.append(...) для добавления в конецсписок.

И поскольку вы изменяете сам список, он изменится в большей области.

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

0 голосов
/ 12 февраля 2019

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

Если вы передадите изменяемый объектв метод, метод получает ссылку на тот же объект, и вы можете изменить его к удовольствию своего сердца, но если вы перепроверете ссылку в методе, внешняя область ничего не будет знать об этом, и после того, как вы закончите,Внешняя ссылка по-прежнему будет указывать на исходный объект.

Если вы передадите неизменный объект методу, вы все равно не сможете перепривязать внешнюю ссылку и даже не можете изменить объект. [подробнее здесь]

...