前ページ(2-10:モジュール・パッケージ・ライブラリ) | 目次へ戻る | 次ページ(3-1:目的を実現するための考え方)
実践編の最後の項目になります。
本ページでは意図せず変数の値が変わる場合に説明していきます。
まずは以下のソースコードを実行してみてください。
・2-11_01_example.py
# 変数の値が変わらない場合
x = 1
y = x
y = y + 1
print("x: ", x)
print("x: ", y)
# 変数の値が変わる場合
x_list = [1, 2, 3, 4]
y_list = x_list
y_list.append(5) # y_listのみを変更
print("x_list: ", x_list) # x_listは変更してないのに変更されている
print("y_list: ", y_list) # y_listは当然変更されている
実行すると以下のような結果になります。
x: 1
x: 2
x_list: [1, 2, 3, 4, 5]
y_list: [1, 2, 3, 4, 5]
ここでおかしなことに気づくと思います。どちらもy、y_listのみの値を変更しているのに、int型の方はx, yがそれぞれちゃんと違う値になっているのに、list型の方はx_listもy_listで変更したのと同じ値になっています。
このように意図せず値が変わってしまう場合があるので注意が必要です。
ちなみに以下のように関数に渡す引数についても同様に値が変わる場合があります。
・2-11_02_example2.py
# 変数の値が変わらない場合
def add(x, y):
y = y + 1
print("x: ", x)
print("x: ", y)
x = 1
y = x
add(x, y)
# 変数の値が変わる場合
def add_y_list(x_list, y_list):
y_list.append(5) # y_listのみを変更
print("x_list: ", x_list) # x_listは変更してないのに変更されている
print("y_list: ", y_list) # y_listは当然変更されている
x_list = [1, 2, 3, 4]
y_list = x_list
add_y_list(x_list, y_list)
実行すると関数の場合も以下のような結果になります。
x: 1
x: 2
x_list: [1, 2, 3, 4, 5]
y_list: [1, 2, 3, 4, 5]
渡した値が変わってしまうかどうかは、Pythonでは以下のように型によって決まっています。
| 変更不可(Immutable)な型 | 変更可能(Mutable)な型 |
|---|---|
| int, float, str, tuple, bytes, frozenset 等 | list, dict, set, bytearray 等 |
基本的には数値や文字列などは変更されないが、それ以外のもの(クラスのオブジェクトなど)は変更されるという風になっています。
値が変更されるlist型などでも、値が変わらないようにして渡したい場合があります。
その場合は「deepcopy」を使います。
import copy
b = copy.deepcopy(a) # aとbは別オブジェクトになる
先ほどの例で実際にdeepcopyを使ってみます。
・2-11_03_deepcopy.py
import copy
x_list = [1, 2, 3, 4]
y_list = copy.deepcopy(x_list) # これでx_listとy_listは別オブジェクトになる
y_list.append(5) # y_listのみを変更
print("x_list: ", x_list) # x_listは変更されていない
print("y_list: ", y_list) # y_listは変更されている
実行すると以下のようにちゃんとx_listとy_listの結果が違っています。
x_list: [1, 2, 3, 4]
y_list: [1, 2, 3, 4, 5]
クラスのオブジェクトを扱う場合など、割とこの問題に遭遇する時があるので頭の片隅にでも入れておくとよいです。
ここまで理解できれば、最低限Pythonでソースコードを書くことができるようになっているはずです。
あとは「python 〇〇 やり方」などで検索して出てきたサンプルなどを動かして、自分がやりたいことをPythonで実現していきましょう。
前ページ(2-10:モジュール・パッケージ・ライブラリ) | 目次へ戻る | 次ページ(3-1:目的を実現するための考え方)