Обработка переменных Python, я не понимаю - PullRequest
6 голосов
/ 23 февраля 2012

Я не могу найти краткую информацию о том, что происходит в этой очень простой программе:

print 'case 1'
# a and b stay different
a = [1,2,3]
b = a
b = [4,5,6]

print 'a =',a
print 'b =',b

print
print 'case 2'
# a and b becomes equal
a = [1,2,3]
b = a
b[0] = 4 
b[1] = 5 
b[2] = 6 

print 'a =',a
print 'b =',b
print

print 'case 3'
# a and b stay different now
a = [1,2,3]
b = a[:]
b[0] = 4 
b[1] = 5 
b[2] = 6 
print 'a =',a
print 'b =',b
print

print 'case 4'
# now the funny thing
a=[1,2,[3]]
b=a[:]
b[0]    = 4 
b[1]    = 5 
b[2][0] = 6 # this modifies b and a!!!

Результат этого простого теста:

case 1
a = [1, 2, 3]
b = [4, 5, 6]

case 2
a = [4, 5, 6]
b = [4, 5, 6]

case 3
a = [1, 2, 3]
b = [4, 5, 6]

case 4
a = [1, 2, [6]]
b = [4, 5, [6]]

Я явно не понимаю, как python обрабатывает каждый случай. Может ли кто-нибудь предоставить ссылку, чтобы я мог прочитать об этом, или краткое объяснение того, что происходит?

Большое спасибо.

Ответы [ 4 ]

9 голосов
/ 23 февраля 2012

Это фантастический инструмент визуализации для кода Python .

Запустите в нем свой код, и все станет ясно через минуту.

6 голосов
/ 23 февраля 2012

Здесь есть две важные вещи:

  • Переменные - это просто метки, указывающие на объекты
  • Список изменчив в Python, а целые - нет.1008 * Когда вы обнаружите, что и a, и b изменены, то это потому, что они оба указывают на один и тот же объект.Вы можете сделать id(a) и id(b), чтобы подтвердить это.

    Что касается примеров, обратите внимание, что a[:] создаст новый объект, который является копией a.Однако это будет мелкая копия, а не глубокая.Это объясняет, почему в примере 4 вы все еще можете изменить a и b.Они указывают на разные объекты списка, но один элемент - это другой список, который используется обоими.

4 голосов
/ 23 февраля 2012

Случай 1: имя b является отскоком.

Случай 2: a и b связаны с одним и тем же объектом.

Случай 3: мелкая копия a связана с b. Списки разные, но объекты в списке одинаковые.

Случай 4: мелкая копия a связана с b, а затем один из объектов видоизменяется.

Переплет не мутирует, а мутация не переплетается.

3 голосов
/ 23 февраля 2012
print 'case 1'
# a and b stay different
a = [1,2,3]
b = a              #At this point 'b' and 'a' are the same, 
                   #just names given to the list
b = [4,5,6]        #At this point you assign the name 'b' to a different list

print 'a =',a
print 'b =',b

print
print 'case 2'
# a and b becomes equal
a = [1,2,3]        #At this point 'b' and 'a' are the same, 
                   #just names given to the list
b = a
b[0] = 4           #From here you modify the list, since both 'a' and 'b' 
                   #reference the same list, you will see the change in 'a'
b[1] = 5 
b[2] = 6 


print 'case 3'
# a and b stay different now
a = [1,2,3]
b = a[:]              #At this point you COPY the elements from 'a' into a new 
                      #list that is referenced by 'b'
b[0] = 4              #From here you modify 'b' but this has no connection to 'a'
b[1] = 5 
b[2] = 6 
print 'a =',a
print 'b =',b
print

print 'case 4'
# now the funny thing
a=[1,2,[3]]
b=a[:]           #At this point you COPY the elements from 'a' into a new 
                 #list that is referenced by 'b'
b[0]    = 4      #Same as before 
b[1]    = 5 
b[2][0] = 6 # this modifies b and a!!!    #Here what happens is that 'b[2]' holds 
                #the same list as 'a[2]'. Since you only modify the element of that 
                #list that will be visible in 'a', try to see it as cases 1/2 just  
                #'recursively'. If you do b[2] = 0, that won't change 'a'
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...