![sec02 - listのコピー(2) [type() と id()]](https://python101.tech/wp-content/uploads/2025/08/eyecatch_185.webp)
このレクチャーでは、前回の『[コラム] Pythonの変数とデータの管理方法』で学習した内容を簡潔に復習しつつ、type()
やid()
関数の使い方を学んでいきます。
Table of Contents(目次)
数値や文字列のtype(), id()を確認する
数値のtype(), id()を確認する
それでは、数値データのtypeとidを確認しながら、Pythonがどのようにデータを管理しているのかを確認しましょう。
データ型を調べるにはtype()
関数を使い、idを調べるにはid()
関数を使います。
num1 = 5
num2 = num1
num3 = 5
num4 = 5.0
print('num1:', num1, type(num1), id(num1)) # 5 <class 'int'> 140715724784680
print('num2:', num2, type(num2), id(num2)) # 5 <class 'int'> 140715724784680
print('num3:', num3, type(num3), id(num3)) # 5 <class 'int'> 140715724784680
print('num4:', num4, type(num4), id(num4)) # 5.0 <class 'float'> 1872433047024
上記コードを実行すると、下図のような出力結果を得られます。(※ただし、id()
の値は、実行するたび変わります。)

int5
が代入された各変数が参照しているid番号は全て同じであることが確認でき、int5
とfloat5.0
は別のデータとして生成され、id番号も変わっていることが確認できます。
文字列のtype(), id()を確認する
文字列の場合のデータの管理方法は、基本的には数値と同じですが、文字の生成方法の違いにより、別のデータとして作成されることがあります。
str1 = 'Hello'
str2 = 'Hello'
str3 = '{}llo'.format('He')
str4 = 'Hello World'[:5]
print('str1:', str1, type(str1), id(str1)) # Hello <class 'str'> 2321373022176
print('str2:', str2, type(str2), id(str2)) # Hello <class 'str'> 2321373022176
print('str3:', str3, type(str3), id(str3)) # Hello <class 'str'> 2321372756752
print('str4:', str4, type(str4), id(str4)) # Hello <class 'str'> 2321373022656
上記コードを実行すると、変数"str1"と"str2"は同じid番号になりますが、"str3"と"str4"は違う番号になります。全ての変数は'Hello'
という文字列が代入されているのですが、format()
メソッドやスライスを使うと、文字の生成方法の違いによって異なるデータとして管理されることが確認できます。
listのtype(), id()を確認する
次に、listとその要素の情報を確認しましょう。(下記コードは、"original_list"を"original"と略して記述しています。)
original = [1, 2, 3]
print('original:', original, type(original), id(original)) # [1, 2, 3] <class 'list'> 2206846990848
print('original[0]:', original[0], type(original[0]), id(original[0])) # 1 <class 'int'> 140715703092136
print('original[1]:', original[1], type(original[1]), id(original[1])) # 2 <class 'int'> 140715703092168
print('original[2]:', original[2], type(original[2]), id(original[2])) # 3 <class 'int'> 140715703092200
コードを実行すると、上記のコメントで説明されているとおり、listやintの情報を得られます。
print(original)
を実行すると、[1, 2, 3]
と出力されるため、数値も内包しているように見えるかもしれません。しかし、listはintの値を内包しているのではなく、それぞれの値のデータを参照していることになります。type()
やid()
を使って情報を確認することにより、Pythonのデータ管理に関する理解が深まります。
(※プログラミングの開発中は、listの要素情報を簡単に確認する必要があるため、[1, 2, 3]
のように出力されることは悪いことではありません。しかし、listなどの構造体をコピーする場面で問題が起こることがあるため、情報の確認方法を知っておく必要はあります。)
コピーしたlistのtype(), id()を確認する
同じlistオブジェクトを参照する例
copied = original
でコピーしたlistのid番号を確認してみましょう。
original = [1, 2, 3]
copied = original
print('original:', original, type(original), id(original)) # [1, 2, 3] <class 'list'> 1896325197824
print('copied:', copied, type(copied), id(copied)) # [1, 2, 3] <class 'list'> 1896325197824
上記コードを実行すると、両方のlistが同じid番号になっていることが確認できます。
異なるlistオブジェクトを参照する例
次のコードのようにlistのデータを生成することで、それぞれの変数は異なるlistを参照することが出来ます。
original = [1, 2, 3]
copied = [1, 2, 3]
print('original:', original, type(original), id(original)) # [1, 2, 3] <class 'list'> 2916726571520
print('copied:', copied, type(copied), id(copied)) # [1, 2, 3] <class 'list'> 2916726483584
original = [1, 2, 3]
copied = original[:]
print('original:', original, type(original), id(original)) # [1, 2, 3] <class 'list'> 1795666379264
print('copied:', copied, type(copied), id(copied)) # [1, 2, 3] <class 'list'> 1795666291328
original = [1, 2, 3]
copied = original.copy()
print('original:', original, type(original), id(original)) # [1, 2, 3] <class 'list'> 2438443153920
print('copied:', copied, type(copied), id(copied)) # [1, 2, 3] <class 'list'> 2438443176704
ネストされたlistのtype(), id()を確認する (Shallow copy)
ネストされたlistの、"外側"と"内側"のlistのidを確認してみます。
original = [[1, 2]]
copied = original.copy()
copied[0][0] = 99
print('original:', original, type(original), id(original)) # [[99, 2]] <class 'list'> 3051058725056
print('copied:', copied, type(copied), id(copied)) # [[99, 2]] <class 'list'> 3051058637248
print('original[0]:', original[0], type(original[0]), id(original[0])) # [99, 2] <class 'list'> 3051058739776
print('copied[0]:', copied[0], type(copied[0]), id(copied[0])) # [99, 2] <class 'list'> 3051058739776
"外側"のlistについては、copy()
メソッドによって複製されたので、違うidになっています。しかし、"内側"のlistについては、同じidになっていることが分かります。そして、"内側"のlistの要素に対して編集が行われると、他方のlistにまで影響が及びます。
つまり、Shallow copy (シャローコピー)では、ネストされたlistの全てを、異なるlistとして扱えないことになります。(※ただし、ネストされたlistの要素に対して編集を行うことが無いのであれば、Shallow copyで十分です。)
Deep copyした後のtype(), id()を確認する
次に、Deep copy(ディープコピー)した後のtype(), id()を確認します。Pythonでは、copyモジュールのdeepcopy()
関数を使用します。
import copy
original = [[1, 2]]
copied = copy.deepcopy(original)
copied[0][0] = 99
print('original:', original, type(original), id(original)) # [[1, 2]] <class 'list'> 1461724428864
print('copied:', copied, type(copied), id(copied)) # [[99, 2]] <class 'list'> 1461724451776
print('original[0]:', original[0], type(original[0]), id(original[0])) # [1, 2] <class 'list'> 1461724327744
print('copied[0]:', copied[0], type(copied[0]), id(copied[0])) # [99, 2] <class 'list'> 1461724332416
ネストされたlistも含め、全てのidが異なっていることが確認できます。これで、ネストされたlistに対して編集を行っても、他方に影響を与えることは無くなります。
(※ ただし、全てを複製することによって、メモリ使用量や処理速度に影響が出ることがありますので、処理の内容によってShallow copyとDeep copyを使い分けましょう。)