TIL|Pythonベース-4



参考資料


https://wikidocs.net/16038

浅い放射と深い放射


浅いコピー

>>> a = [1,2,3,4,5]
>>> b = a
>>> id(a)
140376986310528
>>> id(b)
140376986310528
>>> b[0] = 3
>>> print(a)
[3,2,3,4,5]
baが割り当てられている場合、この値は割り当て値ではなく同じメモリアドレスを有します.
したがって、aの値を持つbを別に作成する場合は、リストaをコピーし、bに割り当てる必要があります.
インデックス、すなわち浅いレプリケーションの1つの方法があります.
>>> a = [1,2,3,4,5]
>>> b = a[:]
>>> id(a)
140377061076480
>>> id(b)
140376986448512
copyモジュールを使用してレプリケーションする方法は、次のとおりです.
import copy

a = [1,2,3,4,5]
b = copy.copy(a)
print(id(a), id(b)) #139881387176320 139881387158080
ただし、どちらのレプリケーション方法も浅いレプリケーションなので、リストに可変オブジェクト(変更可能オブジェクト)が存在する場合、そのオブジェクトの値を変更すると、他の値も同様に変更されます.
簡単に例を挙げると、
import copy

a = [[1,2],[3,4]]
b = copy.copy(a)
b[0][0] = 5
print(a) #[[5, 2], [3, 4]]
aには触れていませんでしたが、bを修正してaも変わりました.
これは、リストbに存在する内部リストが可変であるためである.まだ理解していない場合は、次の例を挙げます.
import copy

a = [9,[1,2,3,4]]
b = copy.copy(a)
b[0] = 5
print(a) #[9,[1,2,3,4]]
print(b) #[5,[1,2,3,4]]
ここで、修正bは、aからアクセスされたオブジェクトb(数字9)の可変オブジェクトであるため、b[0]は変更されない.

可変および非可変


可変表現は、list、set、dictionaryなどの変更可能です.
immutableはint、float、bool、tupleを含む変更不可を示します.
'''
immutable한 객체는 값을 변경하면 참조하는 메모리 주소값도 
바뀌는 것을 볼 수 있습니다.
'''
a = 1
print(id(a)) #140164009412320
a = 2
print(id(a)) #140164009412352

'''
mutable한 객체는 값을 변경해도 주소값이 바뀌지 않는 것을
볼 수 있습니다.
'''
l = [1,2,3]
print(id(l)) #140163937159232
l.append(4)
print(id(l)) #140163937159232
immutableは、現在の変数のメモリ値に従って値を変更できないことを意味します.上記のa = 1は、a = 2とも呼ばれ、新しいオブジェクトに変更されることを意味します.copyモジュールを返して使用するか、インデックスを使用して浅いレプリケーションを行う場合は、リスト内のオブジェクトが可変か可変かによっては、値が同時に変更される場合があります.
可変オブジェクトの場合は、同時に変更されません.可変オブジェクトの場合は、両方のオブジェクトが同時に変更されます.

深くコピー


深いレプリケーションは、浅いレプリケーションと同様に、copyではなくcopy.copy(a)モジュールを使用してレプリケーションされます.
import copy

a = [[1,2,3],[4,5]]
b = copy.deepcopy(a)

b[0][0] = 5
print(a) #[[1,2,3],[4,5]]
print(b) #[[5,2,3],[4,5]]

c = copy.copy(a) 

c[0][0] = 8
print(a) #[[8,2,3],[4,5]]
print(c) #[[8,2,3],[4,5]]