12-Pythonのメモリアドレス

1. メモリアドレスを表示する

a=1
print(id(a)) # 2431929483504

2. データ型
(1) 不変のデータ型:値、文字列、ブール値、タプル
データはコンピュータ内の特定の場所に保存され、誰に割り当てられてもメモリアドレスは同じです

a="jack"
b="jack"
print(id(a))
print(id(b))
# 输出结果相同

この例では、文字列「jack」に対して 2 つのエイリアス a と b が定義されています (つまり、変数名 a、b は文字列のアドレスへの参照です)。これは、この文字列を表現するのに便利です。

a="jack"
b="jack"
print(id(a))
print(id(b))
print(id("jack"))
# 输出均相同

(2) 変数データ型: リスト、辞書、セット
変数データ型の場合、メモリは同じデータを格納するために異なるメモリ アドレスを開きます。

a=[1,2,3]
b=[1,2,3]
print(id(a))
print(id(b))
# 输出结果不同

3. データの変更
(1) 不変のデータ型
異なるデータが異なるアドレスに格納されるため、変数が異なるアドレスを指すことになります。

a=1
print(id(a)) # 2546017632496
a=2
print(id(a)) # 2546017632528

(2) 可変データ型
データの変更は元のアドレスのデータの変更とみなされ、アドレスは変わりません。

a=[1,2,3]
print(id(a)) # 2287597971776
a.append(4)
print(id(a)) # 2287597971776

ネスト 同様に、次の例では、a と b のアドレスは変更されていません。

a=[1,2]
b=[3,a]
print(id(b)) # 2509191607104
a.append(4) # 对a修改,b不受影响
print(id(b)) # 2509191607104

4. 浅いコピー
(1) 直接代入
メモリアドレスをコピーし、一方の値が変化すると他方もそれに追従します。

a=[1,2]
b=a
print(id(a))
print(id(b))
# 相同
a=[1,[2,3]]
b=a
print(id(a[1][0]))
print(id(a[1][0]))
# 相同

(2) コピー方式
(2-1) アドレス空間
① immutable - 単層:同一

import copy
a=2
b=copy.copy(a)
print(id(a),id(b)) # 2110693638416 2110693638416

②可変単層:異なる

import copy
a=[1,2]
b=copy.copy(a)
print(id(a),id(b)) # 2426879856704 2426879856640

③変数の入れ子:全体は違うが内部は同じ

import copy
a=[1,2,[1,2]]
b=copy.copy(a)
print(id(a),id(b)) # 1649968533504 1649968533376
print(id(a[2]),id(b[2])) # 1649968533568 1649968533568
print(id(a[2][0]),id(b[2][0])) # 1649966448880 1649966448880

④不変 - 入れ子:同じ

import copy
a=(1,2,[1,2])
b=copy.copy(a)
print(id(a),id(b)) # 2199230674304 2199230674304
print(id(a[2]),id(b[2])) # 2199230992448 2199230992448
print(id(a[2][0]),id(b[2][0])) # 2199228907760 2199228907760

(2-2) 変形例
①単一階層変数:互いに独立

import copy
a=[1,2]
b=copy.copy(a)
a.append(3)
print(a) # [1, 2, 3]
print(b) # [1, 2]

②単層不変:相互に独立

import copy
a=(1,2)
b=copy.copy(a)
a=(3,4)
print(a) # (3, 4)
print(b) # (1, 2)

③入れ子 - 可変外層 - 可変内層:相互影響

import copy
a=[1,2,[3,4]]
b=copy.copy(a)
a[2].append(5)
print(a) # [1, 2, [3, 4, 5]]
print(b) # [1, 2, [3, 4, 5]]

④ 入れ子 - 外層は可変 - 内層は不変: 相互に影響を与えません。
内部のタプル要素を変更するのは不便です。相互に影響を与えません。

⑤ 入れ子 - 可変外層 - 外層の変更: それぞれ独立

import copy
a=[1,2,(3,4)]
b=copy.copy(a)
a.append(5)
print(a) # [1, 2, (3, 4), 5]
print(b) # [1, 2, (3, 4)]

⑥ 入れ子 – 外層は不変 – 内層は可変:相互影響

import copy
a=(1,2,[3,4])
b=copy.copy(a)
a[2].append(5)
print(a) # (1, 2, [3, 4, 5])
print(b) # (1, 2, [3, 4, 5])

⑦ 入れ子 - 外層不変 - 内層不変: 相互に影響しません。
内部のタプル要素を変更するのは不便です。相互に影響しません。

⑧ネスト-外部不変-外部変更: 相互に影響を与えない
内部タプル要素を変更するのは不便です、相互に影響を与えません

import copy
a=(1,2,(3,4))
b=copy.copy(a)
a=list(a)
a[0]=6
a=tuple(a)
print(a) # (6, 2, (3, 4))
print(b) # (1, 2, (3, 4))
  • 上記の変数データ型の b=copy.copy(a)は b=a.copy() として記述できます (パッケージをインポートする必要はありません)

【演習1】

import copy
a=[1,[2,3]]
b=copy.copy(a)
print(id(a),id(b)) # 不同
print(id(a[1][0]),id(b[1][0])) # 相同

【演習2】

a=[1,[11,22,33],(5,6,7)]
b=a.copy()
print(id(a),id(b)) # 不同
print(id(a[0]),id(b[0])) # 相同
print(id(a[1]),id(b[1])) # 相同
print(id(a[1][0]),id(b[1][0])) # 相同
print(id(a[2]),id(b[2])) # 相同
print(id(a[2][0]),id(b[2][0])) # 相同

【練習問題3】

# 可变数据类型的外部修改:互不影响
a=[1,[11,22,33],(5,6,7)]
b=a.copy()
a.append(6)
print(a) # [1, [11, 22, 33], (5, 6, 7), 6]
print(b) # [1, [11, 22, 33], (5, 6, 7)]

# 可变数据类型的内部可变修改:相互影响
a=[1,[11,22,33],(5,6,7)]
b=a.copy()
a[1].append(6)
print(a) # [1, [11, 22, 33, 6], (5, 6, 7)]
print(b) # [1, [11, 22, 33, 6], (5, 6, 7)]

【練習問題4】

a={
    
    "age":18,"name":"black"}
b=a.copy()
c=a # 拷贝的是内存地址,影响

a["age"]=2000
print(b) # {'age': 18, 'name': 'black'}
print(c) # {'age': 2000, 'name': 'black'}

浅いコピーの概要 (実験データに基づく、参考のみ)
変更:ネストされた変数のデータ型を変更すると、変数の値
も同時に変更されます。

ここに画像の説明を挿入

(3) スライス

a=[1,2,3]
b=a[0:2]
print(b) # [1, 2]
print(a) # [1, 2, 3]
# 对于切片的拷贝,不受影响

5. ディープコピー
(1) メモリアドレス
①単層不変:同一

import copy
a=1
b=copy.deepcopy(a)
print(id(a),id(b)) # 相同

②単層変数:異なる

import copy
a=[1,2,3]
b=copy.deepcopy(a)
print(id(a),id(b)) # 不同

③入れ子 - 外側の層は可変、
外側の層は異なりますが、内側の層は同じです

import copy
a=[(1,2),3,(4,5)]
b=copy.deepcopy(a)
print(id(a),id(b)) # 不同
print(id(a[0]),id(b[0])) # 相同
print(id(a[0][0]),id(b[0][0])) # 相同

④ ネスト - 外側の層は不変であり、
すべて同じです

import copy
a=((1,2),3,(4,5))
b=copy.deepcopy(a)
print(id(a),id(b)) # 相同
print(id(a[0]),id(b[0])) # 相同
print(id(a[0][0]),id(b[0][0])) # 相同

したがって、ディープコピーのメモリアドレスはシャローコピーのメモリアドレスとまったく同じです。

(2) 変形例
① 可変単層:相互に独立

import copy
a=[1,2]
b=copy.deepcopy(a)
a.append(3)
print(a) # [1, 2, 3]
print(b) # [1, 2]

②不変単層:相互に独立

import copy
a=2
b=copy.deepcopy(a)
a=3
print(a) # 3
print(b) # 2

③外層は可変 - 内層は可変 - 入れ子:相互に影響を与えない

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

④ 外側の層は可変 – 内側の層は不変 – 入れ子:相互に影響を与えない

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

⑤ 外層変数 - 外層変更 - 入れ子:相互に影響を与えない

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

⑥ 外層は不変 - 内層は可変 - 入れ子:相互に影響を与えない

import copy
a=(1,[2,3],(4,5))
b=copy.deepcopy(a)
a[1].append(6)
print(a) # (1, [2, 3, 6], (4, 5))
print(b) # (1, [2, 3], (4, 5))

⑦外側の層は不変です - 内側の層は不変です - 入れ子です: 相互に影響しません、
タプルを変更するのは不便です、そしてアドレス空間は基本的に変わります
⑧外側の層は不変です - 外層は変更されます - 入れ子です:
相互に影響しません

ディープコピーの概要:
変更: 各変数は独立
アドレス (シャローコピーと同じ): 不変は同じ、変数は異なる(ネストされた内部も同じ)

ここに画像の説明を挿入

要約する

ここに画像の説明を挿入

おすすめ

転載: blog.csdn.net/weixin_45825865/article/details/130133389