Python の代入と参照

PythonPythonBeginner
今すぐ練習

💡 このチュートリアルは英語版からAIによって翻訳されています。原文を確認するには、 ここをクリックしてください

はじめに

この実験では、Pythonの代入と参照の基本について学びます。Pythonが代入を処理する方法、参照を作成する方法、および可変と不変オブジェクトを扱う方法を探ります。


Skills Graph

%%%%{init: {'theme':'neutral'}}%%%% flowchart RL python(("Python")) -.-> python/BasicConceptsGroup(["Basic Concepts"]) python(("Python")) -.-> python/DataStructuresGroup(["Data Structures"]) python(("Python")) -.-> python/FunctionsGroup(["Functions"]) python(("Python")) -.-> python/PythonStandardLibraryGroup(["Python Standard Library"]) python/BasicConceptsGroup -.-> python/variables_data_types("Variables and Data Types") python/BasicConceptsGroup -.-> python/numeric_types("Numeric Types") python/BasicConceptsGroup -.-> python/strings("Strings") python/DataStructuresGroup -.-> python/lists("Lists") python/FunctionsGroup -.-> python/function_definition("Function Definition") python/FunctionsGroup -.-> python/default_arguments("Default Arguments") python/PythonStandardLibraryGroup -.-> python/data_collections("Data Collections") subgraph Lab Skills python/variables_data_types -.-> lab-14103{{"Python の代入と参照"}} python/numeric_types -.-> lab-14103{{"Python の代入と参照"}} python/strings -.-> lab-14103{{"Python の代入と参照"}} python/lists -.-> lab-14103{{"Python の代入と参照"}} python/function_definition -.-> lab-14103{{"Python の代入と参照"}} python/default_arguments -.-> lab-14103{{"Python の代入と参照"}} python/data_collections -.-> lab-14103{{"Python の代入と参照"}} end

Python代入の紹介

Pythonにおいて、代入とは名前をオブジェクトにバインドするプロセスです。代入文は次の一般的な形式を持ちます。

variable = expression

右辺の式が評価され、その値が左辺の変数に代入されます。

簡単な例を見てみましょう。

単純なテスト

ターミナルを開き、ターミナルに次のコマンドを入力します。

python3

その後、次のコードを入力します。

## 変数 'x' に値42を代入して表示します。
x = 42
print(x)

出力:

42

ここでは、演算子 = を使って変数 x42 を代入しています。その後、x の値を表示しています。

参照の理解

Pythonにおいて、変数はオブジェクトへの参照です。変数に値を代入するとき、実際にはその値を表すオブジェクトへの参照を作成しています。

この概念を説明するための例を以下に示します。

## Pythonの参照を示す。
x = [1, 2, 3]
y = x
y.append(4)

print("x:", x)
print("y:", y)

出力:

x: [1, 2, 3, 4]
y: [1, 2, 3, 4]

この例では、xy の両方が同じリストオブジェクトを参照しています。y を通じて 4 を追加することでリストを変更すると、その変更が xy の両方に反映されます。

可変と不変オブジェクト

Pythonには、可変(mutable)と不変(immutable)の2種類のオブジェクトがあります。

可変オブジェクトは作成後に変更できます。リスト、辞書、セットが可変オブジェクトの例です。

不変オブジェクトは作成後は変更できません。整数、浮動小数点数、文字列、タプルが不変オブジェクトの例です。

可変と不変オブジェクトの違いを示す例を見てみましょう。

## 可変オブジェクトの例
mutable_list = [1, 2, 3]
another_mutable_list = mutable_list
another_mutable_list.append(4)
print("mutable_list:", mutable_list)

出力:

mutable_list: [1, 2, 3, 4]

mutable_list は可変オブジェクトなので、リストの末尾に 4 を追加しますが、不変オブジェクトは作成後は変更できません。

## 不変オブジェクトの例
immutable_string = "hello"
another_immutable_string = immutable_string
another_immutable_string = another_immutable_string.upper()
print("immutable_string:", immutable_string)

出力:

immutable_string: hello

変更はありません。もし immutable_string を次のように変更しようとすると、Pythonシェルは TypeError を投げます。

immutable_string[0] = '1'

出力:

TypeError: 'str' object does not support item assignment

これまで学んだ概念を強化するために、もう少し例を見てみましょう。

例1:可変デフォルト引数を持つ関数

関数のデフォルト引数として可変オブジェクトを使用しないでください。

def bad_append(new_item, a_list=[]):
    a_list.append(new_item)
    return a_list

print(bad_append('one'))

出力:

['one']

うまく見えますが、この関数を再度呼び出すと:

print(bad_append('two'))

出力:

['one', 'two']

ここでの問題は、a_list のデフォルト値が関数定義時に評価されることです。したがって、関数を呼び出すたびに同じデフォルト値が得られます。正しい方法は、代わりに関数内で実行時に作成することです。

def append_to_list(item: int, a_list: list = None) -> list:
    """Append an item to a list and return the updated list."""
    if a_list is None:
        a_list = []
    a_list.append(item)
    return a_list

list_a = append_to_list(1, [1, 2, 3])
print(list_a)

出力:

[1, 2, 3, 1]

例2:可変オブジェクトのコピー

可変オブジェクトのコピーを使いたいときは、copy モジュールを使って新しいオブジェクトを作成します。

import copy

## Demonstrate the use of the copy module.
original_list = [1, 2, 3]
copied_list = copy.copy(original_list)
copied_list.append(4)

print("original_list:", original_list)
print("copied_list:", copied_list)

出力:

original_list: [1, 2, 3]
copied_list: [1, 2, 3, 4]

この例では、copied_listoriginal_list のコピーである新しいオブジェクトです。copied_list4 を追加すると、original_list は変更されません。

例3:可変オブジェクトの深いコピー

ネストされた可変オブジェクトの場合、copy 関数を使うと機能しません。

## your copy example here
original_nested_list = [[1, 2], [3, 4]]
copied_nested_list = copy.copy(original_nested_list)
copied_nested_list[0].append(5)

print("original_nested_list:", original_nested_list)
print("copied_nested_list:", copied_nested_list)

出力:

original_nested_list: [[1, 2, 5], [3, 4]]
copied_nested_list: [[1, 2, 5], [3, 4]]

copied_nested_list5 を追加すると、original_nested_list にも 5 が追加されることがわかります。したがって、代わりに deepcopy 関数を使う必要があります。

## your deepcopy example here
original_nested_list = [[1, 2], [3, 4]]
deep_copied_list = copy.deepcopy(original_nested_list)
deep_copied_list[0].append(5)

print("original_nested_list:", original_nested_list)
print("deep_copied_list:", deep_copied_list)

出力:

original_nested_list: [[1, 2], [3, 4]]
deep_copied_list: [[1, 2, 5], [3, 4]]

この例では、deepcopy 関数は original_nested_list を再帰的にコピーしますが、copy 関数は original_nested_list の1階層目のデータに対する参照オブジェクトを作成します。

まとめ

このPythonプログラミングチュートリアルでは、Pythonの代入と参照の基本を学びました。Pythonが代入をどのように処理するか、参照をどのように作成するか、および可変と不変オブジェクトをどのように扱うかを検討しました。これらの概念を理解することで、効率的で正しいPythonコードを書くことができるようになります。