05-Python

Python(Part.27)| python【選択構造(match文)(2)】|  [Selection Structure] (match statement)(2)

python| まとめ | 現役エンジニア&プログラミングスクール講師「python」のまとめページです。pythonに関して抑えておきたい知識や文法やにについて記事をまとめています。まとめページの下部には「おすすめの学習書籍」「おすすめのITスクール情報」「おすすめ求人サイト」について情報を掲載中...

目標(Objectives)

「match文」について復習する。(To review “match statement”.)
「ORパターン」について理解する(To understand OR Patterns.)
「Asパターン」について理解する(To understand AS Patterns.)
「クラスパターン」について理解する(To understand Class Patterns.)
「ガード」について理解する(To understand Guards.)

詳しくはこちら:PEP 634 – Structural Pattern Matching: Specification

構造的パターンマッチング(match文)
Structural Pattern Matching (match statement)

「match文」は他の言語の「switch文」に似ていますが、パターンマッチングできるオブジェクトに「リスト」や「タプル」などのシーケンスも含まれます。更に、オブジェクトの持つ属性の型や個数のパターンも分岐に利用できます。

The “match statement” is similar to the “switch statement” in other programming languages, but it includes sequences such as “lists” and “tuples” among the objects that can be pattern matched. Furthermore, patterns in the type and number of attributes of objects can also be used for branching.

選択構造(match文)
Selection structure (match statement)

基本制御構造の復習
Review of basic control structures

基本制御構造とは
What is basic control structure

「制御構造」のうち、基本とする3つの構造として「順次構造」「選択構造」「反復構造」が存在します。これらは「基本制御構造」と呼ばれて、次の構造をもっています。

  1. 「順次構造」…プログラムを書かれた順番で実行します。
  2. 「選択構造」…条件の成立・不成立によって実行するプログラムを選択します。
  3. 「反復構造」…条件の成立・不成立によって実行するプログラムを反復します。

Among the “control structures,” there are three basic structures: sequential, selective, and repetitive. These are called “basic control structures” and have the following structure.

  1. Sequential structure: Programs are executed in the order in which they are written.
  2. Selective structure: The program is selected to be executed according to whether the condition is satisfied or not.
  3. Iterative structure: The program to be executed is iterated according to whether the condition is satisfied or not.

「match文」の記述とその動き
Description of “match statement” and its movement

「match文」の記述
Description of “match statement”

「match文」は次のように記述します。下のイラストには記載していませんが、比較させるオブジェクトに「それ以外のオブジェクト」を指定する場合は「_(アンダースコア)」を利用します。

The “match statement” is described as follows. Although not shown in the illustration below, “_ (underscore)” is used to specify “other objects” as the object to be compared.

pythonの「match文」では数値・文字列・リスト・タプル・辞書・クラス・などの比較ができます。
The “match statement” in python allows you to compare numbers, strings, lists, tuples, dictionaries, classes, etc.

【English translation of captcha】
パターンマッチングされるオブジェクト
→Objects to be pattern matched
比較されるオブジェクト
→Contents of object being compared
ブロック
→Block

「match」の動き(4)/ The “match” movement (4)

変数「Objects_to_be_pattern_matched」にcaseで比較する値を指定すると、其々のブロックが処理されます。「|」を利用すると複数のオブジェクトを設定することが可能です。
If the variable “Objects_to_be_pattern_matched” is set to a value to be compared within a case, the corresponding block is processed. Multiple objects can be set by using “|”.

Objects_to_be_pattern_matched = "autumn"

match Objects_to_be_pattern_matched:
    case "spring":
        print('It\'s spring.')
    case "summer":
        print('It\'s summer.')
    case "autumn" | "fall":
        print('It\'s autumn (fall).')
    case "winter":
        print('It\'s winter.')

実行結果:変数「Objects_to_be_pattern_matched」が「”autumn”」または「”fall”」のとき。
Execution result: When the variable “Objects_to_be_pattern_matched” is “autumn” or “fall”.

caseの後に「|」を利用して複数のオブジェクトを持たせることが可能です。これは、「ORパターン」と呼ばれ、指定した値のいずれかが該当した場合、このブロックが処理されます。
It is possible to have multiple objects by using “|” after “case”. This is called an “OR patterns” and this block will be processed if any of the specified values apply.

「match」の動き(5)/ The “match” movement (5)

ASパターンを利用するとcaseの後に指定した変数にオブジェクト(リテラル等も含む)を結びつけることができます。
The AS pattern can be used to bind an object (including literals, etc.) after the “case” to a variable specified after the “as”.

Objects_to_be_pattern_matched = "autumn"

match Objects_to_be_pattern_matched:
    case "spring" as season:
        print('It\'s',season,'.')
    case "summer" as season:
        print('It\'s',season,'.')
    case "autumn" | "fall" as season:
        print('It\'s',season,'.')
    case "winter" as season:
        print('It\'s',season,'.')

実行結果:変数「Objects_to_be_pattern_matched」が「”autumn”」のとき。
Execution result: When the variable “Objects_to_be_pattern_matched” is “autumn”.

case の後にオブジェクト(リテラルなどを含む)を設定し、更にその後に「as 変数名」として、オブジェクトをasの後に指定した変数にバインドするものを「ASパターン」と呼びます。
An object (including literals, etc.) is set after “case”, followed by “as variable name” and the object is bound to the variable specified after “as” is called the “AS patterns“.

「match」の動き(6)/ The “match” movement (6)

クラスパターンを利用するとインスタンスの持つ属性を比較してマッチングさせることができます。
The class pattern can be used to compare and match the attributes that an instance has.

class Season:

    in_what_season: str

    def __init__(self, in_what_season: str) -> None:
        self.in_what_season = in_what_season

season = Season("Spring")

match season:
    case Season(in_what_season = "Winter"):
        print('It\'s winter.')
    case Season(in_what_season = "Spring"):
        print('It\'s spring.')
    case Season(in_what_season = "Summer"):
        print('It\'s summer.')
    case Season(in_what_season = "Autumn"):
        print('It\'s autumn.')

実行結果:インスタンスが「season = Season(“Spring”)」のとき。
Execution result: When the instance is “season = Season(”Spring“)”.

クラスのインスタンスに対し、インスタンスの持つ属性を比較しマッチングパターンを行うものを「クラスパターン」と呼びます。
A “Class patterns” is a matching pattern for instances of a class by comparing the attributes of the instances.

「match」の動き(7)/ The “match” movement (7)

クラスパターンは継承後のクラスのインスタンスにも利用できます。
The “class pattern” can also be used for instances of the class after inheritance.

class Season:

    in_what_season: str

    def __init__(self, in_what_season: str) -> None:
        self.in_what_season = in_what_season

season = Season("Spring")

class Month (Season):

    in_what_month: int

    def __init__(self, in_what_season: str, in_what_month: int) -> None:
        super().__init__(in_what_season)

        self.in_what_month = in_what_month

month = Month("Spring", 4)

match month:
    case Month(in_what_season = "Winter", in_what_month = 12 | 1 | 2 as month_num):
        print('It\'s the {}th month of year and it\'s winter.'.format(month_num))
    case Month(in_what_season = "Spring", in_what_month = 3 | 4 | 5 as month_num):
        print('It\'s the {}th month of year and it\'s spring.'.format(month_num))
    case Month(in_what_season = "Summer", in_what_month = 6 | 7 | 8 as month_num):
        print('It\'s the {}th month of year and it\'s summer.'.format(month_num))
    case Month(in_what_season = "Autumn", in_what_month = 9 | 10 | 11 as month_num):
        print('It\'s the {}th month of year and it\'s autumn.'.format(month_num))

実行結果
Execution result

インスタンス化時に複数の引数を利用する場合、名前付き引数で値を指定せずに、位置引数で指定することが可能です。
When multiple arguments are used during instantiation, it is possible to specify them as positional arguments instead of specifying values with named arguments.

このためにはクラスの中で「 __match_args__」を利用して引数に指定した値を、値の入力順に対して、その引数の名前をマッチングさせる設定を行います。
To do this, use “__match_args__” in the class to set the values specified as arguments to match the names of the arguments against the input order of values.

また、これはクラスに「@dataclass」を付けることでも同様の設定が暗黙的に行われることになります。
This is also implicitly done by adding “@dataclass” to the class.

これは引数の値がタプルとして扱われなければいけません。引数の数がひとつの場合は利用できません。
This requires that the argument values be treated as a tuple. It is not available when the number of arguments is one.

上のプログラムを次のように書き換えます。
Rewrite the above program as follows

class Season:

    in_what_season: str

    def __init__(self, in_what_season: str) -> None:
        self.in_what_season = in_what_season

season = Season("Spring")

class Month (Season):

    __match_args__ = ("in_what_season", "in_what_month")

    in_what_month: int

    def __init__(self, in_what_season: str, in_what_month: int) -> None:
        super().__init__(in_what_season)

        self.in_what_month = in_what_month

month = Month("Spring", 4)

match month:
    case Month("Winter", 12 | 1 | 2 as month_num):
        print('It\'s the {}th month of year and it\'s winter.'.format(month_num))
    case Month("Spring", 3 | 4 | 5 as month_num):
        print('It\'s the {}th month of year and it\'s spring.'.format(month_num))
    case Month("Summer", 6 | 7 | 8 as month_num):
        print('It\'s the {}th month of year and it\'s summer.'.format(month_num))
    case Month("Autumn", 9 | 10 | 11 as month_num):
        print('It\'s the {}th month of year and it\'s autumn.'.format(month_num))

これを実行すると先ほどと同じ実行結果が得られます。
This will produce the same results as the previous run.

実行結果
Execution result

「match」の動き(8)/ The “match” movement (8)

match文ではcaseが利用するオブジェクトの属性やリテラルに対してif文を利用し、詳細な条件を設定することができます。
The match statement uses if statements for the attributes and literals of the objects used by the case, and allows detailed conditions to be set.

month = 8
match month:
    case month if 1 <= month <= 2 or month == 12:
        print('Iit\'s winter.')
    case month if 3 <= month <= 5:
        print('It\'s spring.')
    case month if 6 <= month <= 8:
        print('It\'s summer.')
    case month if 9 <= month <= 11:
        print('It\'s autumn.')

実行結果
Execution Result

caseが利用するオブジェクトの属性やリテラルに対してif文を利用し、詳細な条件を設定することを「ガード」と呼びます。
The use of if statements for the attributes and literals of the objects used by the “case” to set detailed conditions is called “Guards“.

クラスパターンの属性にガードを利用すると次のようになります。
The use of guards for class pattern attributes is as follows.

class Season:

    in_what_season: str

    def __init__(self, in_what_season: str) -> None:
        self.in_what_season = in_what_season

season = Season("Spring")

class Month (Season):

    __match_args__ = ("in_what_season", "in_what_month")

    in_what_month: int

    def __init__(self, in_what_season: str, in_what_month: int) -> None:
        super().__init__(in_what_season)

        self.in_what_month = in_what_month

month = Month("Spring", 4)

match month:
    case Month("Winter", int(in_what_month)) if 1 <= in_what_month <= 2 or in_what_month == 12:
        print('It\'s the {}th month of year and it\'s winter.'.format(in_what_month))
    case Month("Spring", int(in_what_month)) if 3 <= in_what_month <= 5:
        print('It\'s the {}th month of year and it\'s spring.'.format(in_what_month))
    case Month("Summer", int(in_what_month)) if 6 <= in_what_month <= 8:
        print('It\'s the {}th month of year and it\'s summer.'.format(in_what_month))
    case Month("Autumn", int(in_what_month)) if 9 <= in_what_month <= 11:
        print('It\'s the {}th month of year and it\'s autumn.'.format(in_what_month))

実行結果
Execution Result

今回は以上になります。
That’s all for this time.

「python」おすすめ書籍 ベスト3 | 現役エンジニア&プログラミングスクール講師「python」の学習でお勧めしたい書籍をご紹介しています。お勧めする理由としては、考え方、イメージなどを適切に捉えていること、「生のpython」に焦点をあてて解説をしている書籍であることなどが理由です。勿論、この他にも良い書籍はありますが、特に質の高かったものを選んで記事にしています。ページの下部には「おすすめのITスクール情報」「おすすめ求人サイト」について情報を掲載中。...

ブックマークのすすめ

「ほわほわぶろぐ」を常に検索するのが面倒だという方はブックマークをお勧めします。ブックマークの設定は別記事にて掲載しています。

「お気に入り」の登録・削除方法【Google Chrome / Microsoft Edge】「お気に入り」の登録・削除方法【Google Chrome / Microsoft Edge】について解説している記事です。削除方法も掲載しています。...
【パソコン選び】失敗しないための重要ポイント | 現役エンジニア&プログラミングスクール講師【パソコン選び】失敗しないための重要ポイントについての記事です。パソコンのタイプと購入時に検討すべき点・家電量販店で見かけるCPUの見方・購入者が必要とするメモリ容量・HDDとSSDについて・ディスプレイの種類・バッテリーの持ち時間や保証・Officeソフト・ウィルス対策ソフトについて書いています。...
RELATED POST