Pythonで〇×ゲームのAIを一から作成する　その4　配列 と list 型のデータ

# 目次と前回の記事

https://qiita.com/ysgeso/items/2381dd4e3283cbed49a0

https://qiita.com/ysgeso/items/1b7b1abe942e2d10c0b4

# 前回のおさらい

前回の記事では、以下のような〇×ゲームの仕様を決め、仕様 1 を最初に実装することに決めました。

1. 正方形で区切られた 3 x 3 の 2 次元のゲーム盤上でゲームを行う
2. ゲーム開始時には、ゲーム盤の全てのマスは空になっている
3. 2 人のプレイヤーが遊ぶゲームであり、一人は 〇 を、もう一人は × のマークを受け持つ
4. 2 人のプレイヤーは、交互に空いている好きなマスに自分のマークを 1 つ置く
5. 先手は 〇 のプレイヤーである
6. プレイヤーがマークを置いた結果、縦、横、斜めのいずれかの一直線の 3 マスに同じマークが並んだ場合、そのマークのプレイヤーの勝利とし、ゲームが終了する
7. すべてのマスが埋まった時にゲームの決着がついていない場合は引き分けとする

仕様 1. を実装するためには、3 x 3 の __2 次元のゲーム盤__ を表すデータを __プログラムで記述__ する必要があります。そのためには、__配列__ と Python の __list 型のデータ__ について学ぶ必要があります。

今回の記事はこの 2 つについて詳しく説明します。

## 配列 と list 型のデータ

ほとんどのプログラム言語には、__配列__ という __複数のデータをまとめて扱う__ ことができるデータ型が用意されています。〇×ゲームのゲーム盤のように、__2 次元の座標__ で表現されるデータは、__2 次元配列__ を利用するのが直観的でわかりやすい方法でしょう。

配列や 2 次元配列という用語の説明をいきなりしてもわかりにくいと思いますので、先に配列の性質を持つ Python のデータ型の 1 つである __list__ について説明します。

:::note
「list 型のデータ」のように記述すると文章が長くなるので、そのことを強調したい場合でない限り、以降は「list 型のデータ」のことを単に「list」と記述します。
:::

https://docs.python.org/ja/3/library/stdtypes.html#list

はじめに、Python の list の基本的な性質と用語についてまとめ、その後でそれぞれの性質や用語について説明します。なお、Python の list には下記以外にも様々な性質がありますが、それらについては必要に応じて説明する予定です。

:::note warn
__Python の list の基本的な性質と用語__

* list は __複数のデータ__ を __順番に__ まとめて扱うことができる Python の __データ型__ である
* list は、半角の `[` と `]` の間に、list に格納する個別のデータを半角の `,` で区切って __順番に__ 記述する
* list に格納された個別のデータの事を list の __要素__ と呼ぶ
* list の要素には、__先頭の要素から順番__ に __0 からはじまる整数の番号__ が付けられており、その番号を使って list 内の個別の要素を参照することができる
* list の要素を参照するための番号のことを list の __インデックス__ [^1]と呼ぶ
* 上記の性質から、list の要素は __0 以上の整数__ のインデックスを使って、__順序付けられている__
* list の要素の参照は、半角の `[` と `]` を使って、__`listのデータ[インデックス]`__ のように記述する
* list の要素は __変数と同様の性質__ を持ち、Python の __任意のデータ型のデータ__ を代入したり、式の中で記述して要素に代入されたデータを参照することができる
:::

:::note
「データ型のデータ」という表現は、同じ「データ」という用語が並んでいてわかりづらいので、以降は「データ型のデータ」のことを、単に「__データ型__」と表記します。
:::

### 参照の意味

上記の説明の中の「参照」という用語がわかりづらいかもしれないので以下に補足します。下記の __参照__ と __識別子__（または id）という用語は、良く使われる __重要なプログラミング用語__ なので必ず意味を理解してください。

:::note warn
list のインデックスのように、番号や住所などの __識別子__ を使って __特定のものを指定__ することを __参照__ と呼びます。識別子の英語は __identifier__ で、よく先頭の 2 文字をとって __id__ と表記されます。

識別子に求められる __重要な性質__ として、異なるものを参照する識別子には、__必ず異なる識別子が付けられる__ というものがあります。

例えば「住所」、「電話番号」、「マイナンバー」などは識別子ですが、人を参照する際に良く使われる「氏名」は、__同姓同名の可能性がある__ ため、氏名だけでは厳密な意味では識別子とは言えません。
:::

list のインデックスが list の要素を参照する以外でも、プログラムでは、__様々な識別子__ をって、様々なものを __参照__ します。例えば、「__変数名__」は、変数に __代入された値__ を参照する識別子です。従って、「変数の値」を、「変数名が参照する値」のように言い換えることができます。

__複数の識別子__ を使って __参照__ が行われる場合もあります。例えば、list を変数に代入した場合は、その「変数名」と、「インデックス」の __2 つの識別子__ を使って、`a[1]` のように list の要素の値を参照します。`a[1]` の意味についてはこの後で説明します。

### list の記述方法

Python の list は、半角の `[` と `]` の間に、list に格納する個別のデータを半角の `,` で区切って __順番に__ 記述します。下記のプログラムは、100、200、300 という 3 つのデータを格納した list を `a` という変数に代入しています。

`print` を使って list を表示すると、下記の実行結果のように、その list をプログラムで記述した場合と同じ内容が表示されます。

```python
a = [ 100, 200, 300 ]
print(a)
```
実行結果
```
[100, 200, 300]
```

:::note
本記事が利用している Qiita では、上記のようにプログラムの文字が、Python の構文（syntax）（文法のこと）規則によって __色分け__ されて表示されます。このような表示の事を __シンタックスハイライト__ (syntax highlight）と呼びます。

どのように色分けが行われるかは、__ソフトによって異なります__。Qiita では、数値型のデータが紫色、文字列型のデータが水色、`print` などの組み込み関数は緑色、などのように色分けが行われます。色分けの種類はかなり多いので、本記事では具体的には紹介しませんが、慣れてくればどの色が何を表すのかがわかるのようなるのではないかと思います。

プログラムを入力する際に、シンタックスハイライトは __入力ミスを見つける__ 大きな __手掛かり__ となります。入力したプログラムの文字の色がいつもと違うと思ったら、何らかの入力ミスがある可能性が高いと考えたほうが良いでしょう。

VSCode で入力されたプログラムもシンタックスハイライトが行われますが、色分けのルールは Qiita とは異なっている点に注意して下さい。また、VSCode では、設定を行うことによってシンタックスハイライトの色を自由に変更することもできるようです。

なお、本記事のプログラムの __実行結果__ には、構文などはありませんので、__色分けは行いません__。
:::

::: note
本記事では、プログラムに記述する内容を本文中に表記する場合は `print` のように、灰色の背景で表記します。
:::

### list の要素とインデックス

list に関連する重要な用語に __要素__ と __インデックス__ があります。それぞれ以下のような意味を持つので必ず理解して下さい。

* list に格納された個別のデータの事を list の __要素__ と呼ぶ
* list の要素には、__先頭の要素から順番__ に __0 からはじまる整数の番号__ が付けられており、その番号を使って list 内の個別の要素を参照することができる
* list の要素を参照するための番号のことを list の __インデックス__ と呼ぶ

先程のプログラムで記述した `[100, 200, 300]` という list の、100、200、300 の 3 つの要素のインデックスは、それぞれ 0、1、2 に対応しています。

:::note warn
プログラム言語では、list のインデックスの数字を 1 からではなく、__0 から数える__ 点に注意して下さい。なお、プログラムではインデックスに限らず、数字を 0 から数えるのが __一般的__ です。
:::

### list の要素への代入と参照

list の要素は、インデックスと半角の `[` と `]` を使って、__`listのデータ[インデックス]`__ のように記述して参照します。例えば `a` に list が代入されていた場合、`a` の 1 番のインデックスの要素は、`a[1]` のように記述します。

:::note
「`a` の 1 番のインデックスの要素」のように記述すると表記が長くなってしまうので、以後は「`a` の 1 番の要素」のように、__「インデックス」を省略__ して表記します。
:::

list の要素は __変数と同様の性質を持つ__ ので、list の要素に対して代入文を記述して __値を代入__ したり、list の要素を式の中で記述することで __代入された値を取り出して__ 計算を行うことができます。


下記のプログラムは、以下の処理を行います。

* 1 行目で `a` に `[100, 200, 300]` という list を代入する
* 2 行目で `a` の 1 番の要素 + `50` を計算してを表示する
* 3 行目で `a` の 2 番の要素に `500` を代入する
* 4 行目で `a` の値を表示する

2 行目を実行すると list の 1 番の要素の値である `200` と`50` が加算されて `250` が表示されます。この `a[1] + 50` は __代入文ではない__ ので、この計算が行われても `a[1]` の内容は __変化しません__。この点を __勘違い__ しないように注意して下さい。

3 行目で list の 2 番の要素に `500` を代入しているので、 4 行目の表示では list の 2 番の要素の値が `500` に変化しています。

```python
a = [100, 200, 300]
print(a[1] + 50)
a[2] = 500
print(a)
```
実行結果
```
250
[100, 200, 500]
```
:::note warn
__慣れないうちは勘違いしがち__ ですが、「list の 1 番の要素」を、list の先頭の要素であると勘違いしないように気を付けて下さい。先ほど説明したように、インデックスは __0 から数える__ ので、「list の 1 番の要素」は、先頭の要素を 1 __番目__ として数えると 2 __番目__ の要素になります。

本記事ではこのことを区別するために、先頭の要素を 1 番目として数えた場合は、「〇 __番目__ の要素」のように、__番目__ という用語を太字で記述して区別できるようにすることにします。なお、そのように区別しても紛らわしいことには変わりはないので、基本的には「〇 __番目__ の要素」という表現はできるだけしないようにするつもりです。
:::

### 配列と list の意味の違い

まず、配列という用語の意味を説明します。

::: note warn
__0 以上の整数__ を __識別子__ として、複数のデータを __順番にまとめて__ 扱えるようなデータのことを __配列__ と呼びます。
:::

Python の list は上記の __配列の性質を持つ__ データ型なので、Python の list のことを配列と表現することが良くありますが、配列という用語と list という用語は __同じ意味を持つわけではありません__。

配列は __データが持つ性質__ の事を表し、多くのプログラム言語では配列の性質を持つデータを __様々な方法で扱う__ ことが可能です。Python の list は、Python が扱うことができる、配列の性質を持つデータを表現する方法の __中の 1 つ__ にすぎません。現実の世界で例えると、配列は「スポーツ」のような __分類__ を表し、list は「サッカー」のようなスポーツに __分類されるもの__ のうちの 1 つに相当します。

実際に Python には、list 以外にも、array という配列の性質を持つデータ型があります。ただし、array と list は多くの点で似てはいますが、いくつか異なる性質を持っています[^2]。

他にも Python には numpy という非常に良く使われるモジュールがあり、numpy を利用することで Python の list や array とは異なる配列の性質を持つデータを扱うことができます[^3]。

Python の list は 配列の性質を持つので、list の事を配列と表記しても間違いではありませんが、Python では配列の性質を持つデータを __複数の方法__ で扱うことができるので、単に配列と記述するとそれらのうちのどれ表しているかが __不明確__ になります。そこで、本記事では配列と list という用語を以下のように __使い分ける__ ことにします。

:::note warn
本記事では「list」と「配列」という用語を以下のように使い分けます。
* Python のデータ型である list を指す場合は配列ではなく、__list__ と表記します。
* 「0 以上の整数を識別子として、複数のデータを順番にまとめて扱えるようなデータ」という、配列の __性質__ を表したい場合は __配列__ と表記します。
:::

:::note
本記事で、list を「リスト」のようなカタカナではなく、アルファベットで表記しているのは、__データの性質__ を表す「リスト」という __プログラミングの用語がある__ からです。本記事は日本語で書かれているので、list のようにアルファベットで表記することで、list が Python という __特定の__ プログラミング言語のデータ型であるということを表現しました。
:::

### 複合データ型の定義

list は、その要素の中に Python の __任意のデータ型__ を代入できます。プログラミングの用語では、このように、複数のデータ型を __組み合わせて表現__ されるデータ型のことを、__複合データ型__ （または、複合型のデータ型）と呼びます。

プログラム言語によって、どのようなデータ型を複合データ型と分類するかは異なります。また、色々と調べてみたのですが、Python では、データ型を複合データ型という性質で分類することはあまりないように思えました。

そこで、本記事では __複合データ型__ という __データ型を分類__ する用語を、以下のように __定義__ します。他の Python の記事ではこの用語が __別の意味__ で使用される可能性がある点に注意して下さい。

:::note warn
Python の __任意のデータ型__ を、__複数組み合わせて__ データを表現するデータ型
:::

Python では、list、dict、tuple などが複合データ型に分類されます。dict、tuple に関しては、必要になった時点で説明します。

:::note
Python では、list、dict、tuple などは、__コンテナ__（container）に __分類__ されます。コンテナは、文字通り、__複数のデータ__ を __格納__（contain）できるデータのことですが、Python のコンテナに分類される __文字列型__ のデータは、その中に __文字だけしか格納__ することが __できません__。そこで、本記事では __複合データ型__ という用語を Python の __任意のデータ型を格納__ できるという意味で、コンテナという用語と __区別して使う__ ことにします。
:::

### 1 次元配列と 2 次元配列

Python の list は、インデックスを __1 つ指定__ して特定の要素を参照します。このように、__1 つの識別子__ を使って複数のデータをまとめて扱うような配列のことを __1 次元配列__ と呼びます。

しかし、3 x 3 のマスで構成される〇×ゲームのようなゲーム盤のマスは、x 座標と y 座標の __2 つの座標__ で参照するのが一般的です。そのため、1 次元配列はゲーム盤のデータを表現するにはあまり向いているとは言えません。

そのような場合は、__2 つの識別子__ を使って複数のデータをまとめて扱うことができる __2 次元配列__ [^4] を使うのが一般的と言えるでしょう。

Python では list の要素に list を __入れ子で代入する__ ことで 2 次元配列を表現できます。
このことは、初心者にはわかりづらい部分があると思いますので、具体例を挙げながら順を追って説明します。

:::note
複数の識別子を使って、複数のデータの中から 1 つのデータを参照する場合、1 つ 1 つの識別子の事を __次元__（dimension）と呼びます。また、識別子の数が `n` 個の場合は、そのデータを参照する識別子の事を __n 次元のデータ__ と呼びます。

数学で使われる 2 次元平面の座標は、「x 座標」と「y 座標」の 2 次元で平面上の 1 つの点を参照するので 2 次元のデータです。我々が生きている 3 次元空間の座標は一般的に、「x 座標」、「y 座標」、「z 座標」の 3 次元で空間上の 1 つの点を参照するので 3 次元のデータです。

3 次元までのデータであれば、その分布を紙に書いたり、頭の中で思い浮かべたりすることができます。4 次元以上のデータの分布を紙に書いたり、頭の中に思い浮かべることは容易ではありませんが、次元の数に __上限はありません__。例えば、ある高校で行われた期末テストの生徒の点数を、「学年」、「クラス」、「出席番号」、「科目」の 4 つの次元の識別子で参照する場合、それらの識別子は 4 次元のデータです。
:::

### 2 次元配列を表す list の記述方法

下のような 3 x 3 の表で、セルの中に左上から順に 1 から 9 までのデータが格納された表を、Python の list で表現することを考えてみます。なお、この表は以下のような意味を持つものとします。

* 左右方向を x 座標、上下方向を y 座標で表現する
* 図の太字の部分は x、y 座標の番号を表す
* 表のセルを x 座標と y 座標の __2 次元のデータ__ の座標で参照する
* 表のセルの座標を、x 座標と y 座標の番号を使って、(1, 2) のように表現する
* この表の場合、(1, 2) のセルには 8 が格納されている

:::note warn
以降は __〇×ゲームのゲーム盤の座標__ もこの座標で表記することにします。
:::

|  | 0 | 1 | 2 |
|:-:|:-:|:-:|:-:|
| __0__  | 1  | 2  | 3  |
| __1__  | 4  | 5  | 6  |
| __2__  | 7  | 8  | 9  |

:::note
表計算ソフト Excel のセルの行の座標や、将棋盤のマスの座標などでは、座標は 1 から数えますが、プログラムでは 0 から数えるのが一般的なので、上記の表でも座標を 0 から数えています。
:::

:::note warn
配列のインデックスの性質から、上記の表のデータのように __0 から始まる整数の識別子__ を使って複数のデータの中から 1 つのデータを参照するようなデータは __配列が適しています__。
:::


Python の list は、そのままでは 1 つのインデックスで要素を参照するので、上記のような 2 次元の表のデータを直接表現することはできません。しかし、この表を __列ごとに分けて__ 考えると、各列のデータは __1 つの__ インデックスに、`0`、`1`、`2` という y 座標を表す数値を対応させた list で表現することができます。そこで、この表のデータを列ごとに list で表現することにします。

この表の 0、1、2 列のデータを list で表現すると、下記のプログラムのようになります。下記のプログラムでは、`col0`、`col1`、`col2`[^5] という変数にそれぞれ 0、1、2 列を表す list を代入しています。

```python
col0 = [1, 4, 7]
col1 = [2, 5, 8]
col2 = [3, 6, 9]
```
:::note
列は __縦方向のデータ__ なので、`col0 = [1, 2, 3]` __ではない__ 点に注意して下さい。

なお、列ではなく、行ごとに list でデータを記述することもできます。その場合の表のデータの記述方法と、列ごとに記述した場合の違いなどについては後述します。
:::
例えば、1 列のデータは下記のように `print(col1)` を実行することで表示することができます。

```python
print(col1)
```
実行結果
```
[2, 5, 8]
```

:::note
繰り返しになりますが、list ではインデックスは 1 ではなく __0 から数字を数えます__。従って「1列のデータ」は一番左の列のデータではなく、左から 2 __番目__ の列のデータを表す点に注意して下さい。
:::

1 列の 2 行、すなわち (1, 2) のセルのデータは　`col1[2]` に代入されているので、下記のプログラムで表示することができます。

```python
print(col1[2])
```
実行結果
```
8
```

Python では 2 次元配列を表すデータを、__list の要素に list を代入する__ という方法で記述することができます。具体的には下記のプログラムのように、__list が代入されている__ `col0`、`col1`、`col2` を要素として持つ list を記述します。

下記のプログラムでは、`table`[^6] という名前の変数にそのデータを代入しています。

```python
table = [ col0, col1, col2 ]
```

`table` に代入された list の要素は順番に、0 列のデータ、1 列のデータ、2 列のデータを表します。従って、下記のように`print(table[1])`を実行することで、先ほどの`print(col1)`と同様に、1 列のデータを表す list を表示することができます。

```python
print(table[1])
```
実行結果
```
[2, 5, 8]
```
`table[1]` が `col1` と同様に、1 列のデータを表すことがわかったので、(1, 2) のセルの要素は `col1[2]` の `col1` の部分を `table[1]` で __置き換えた__ `table[1][2]` のように記述することができます。そのことは下記のプログラムを実行すると、実行結果のように (1, 2) のセルの中身である `8` が表示されることで確認できます。

```python
print(table[1][2])
```
実行結果
```
8
```

このようにして記述された 2 次元配列を表す list は、上記のように __2 つのインデックス__ を指定することで、1 つの要素を参照することができます。上記の場合は、(x, y) のマスを表す要素を `table[x][y]` のように記述します。

### 2 次元配列を表す list を直接記述する方法

先程のプログラムでは、列のデータを表す list を __一旦変数に代入してから__ 2 次元配列を表す list を記述していましたが、下記のプログラムのように、list の要素に __変数を記述して代入していた__ 部分に __list のデータを直接記述__ するができます。

:::note
下記のプログラムでは、先ほどのプログラムの `table` と区別するために、別の `table2` という名前の変数に表のデータを代入しています。
:::

`table2` に代入した表のデータは、先ほどのプログラムの記述の仕方は異なりますが、`table` に代入した表のデータと __全く同じもの__ を表すので、下記の 2 行目を実行すると (1, 2) のセルの内容が正しく表示されます。

```python
table2 = [[1, 4, 7], [2, 5, 8], [3, 6, 9]]
print(table2[1][2])
```
実行結果
```
8
```
:::note warn
上記のプログラムからわかるように、Python では、list の中に list を __入れ子で記述する__ ことで、2 次元配列のデータを記述することができます。
:::

分かりづらいと思った方は、下記の先ほどのプログラムと見比べて下さい。まず、下記のプログラムの 4 行目の `col0` を、1 行目で `col0` に代入した　`[1, 4, 7]` に置き換えて下さい。4 行目の `col1` と `col2` も同様の方法で置き換えると上記のプログラムのようになります。

```python
col0 = [1, 4, 7]
col1 = [2, 5, 8]
col2 = [3, 6, 9]
table = [col0, col1, col2]
```

2 次元配列を表す list を `print` で表示した場合は、下記のプログラムの実行結果のように、list をすべて __直接記述した場合と同じ内容__ が表示されます。`table` と `table2` の内容の表示結果が同じになることを確認して下さい。

```python
print(table)
print(table2)
```
実行結果
```
[[1, 4, 7], [2, 5, 8], [3, 6, 9]]
[[1, 4, 7], [2, 5, 8], [3, 6, 9]]
```

:::note
__1 行__ で 2次元配列のデータを記述するのがわかりづらいと思った方は、下記のように列のデータごとに改行して記述すると良いでしょう。

ただし、実行結果からわかるように、このように記述しても `print` でその内容を表示すると __1 行でまとめて__ 表示が行われます。

```python
table3 = [
    [1, 4, 7],
    [2, 5, 8],
    [3, 6, 9]
]
print(table3[1][2])
print(table3)
```
実行結果
```
8
[[1, 4, 7], [2, 5, 8], [3, 6, 9]]
```
:::

:::note
今回の記事では具体例は示しませんが 3 次元以上の配列のデータも同様に、__次元の数だけ__ list の中に list を __入れ子__ にして記述します。3 次元以上の配列のデータの具体例については、本記事で必要になった時に紹介します。
:::

### Python のコメント

Python では、半角の # を記述することで、__その行のそれ以降__ にコメント（注釈）を記述することができます。コメントとして記述した内容は、プログラムの内容とはみなされず __実行されることはありません__ 。

__本記事__ で表示するプログラムのコメントは __灰色の文字__ で表示されます。また、__VSCode__ ではコメントの部分は __緑色の文字__ で表示されるので一目で区別がつくようになっています。

下記のプログラムは、上記のノートのプログラムにコメントをつけ加えたものです。`table3` に代入する list の 3 つの 要素が、それぞれ何列のデータを表すかをコメントで記述しています。

```python
table3 = [
    [1, 4, 7], # 0 列のデータ
    [2, 5, 8], # 1 列のデータ
    [3, 6, 9]  # 2 列のデータ
]
```
このように、適切なコメントを記述することで、プログラムの意味が __分かりやすくなります__。
ただし、コメントを書きすぎると __逆にプログラムがわかりにくくなる__ こともあります。コメントは、分かりづらいと思ったところなどに __ピンポイント__ で記述することをお勧めします。

### 2 次元配列のインデックスの順番

これまでのプログラムでは、2 次元配列の 2 つのインデックスは順に「x座標」、「y座標」という意味を持ちましたが、その順番を逆にして「y座標」、「x座標」の順にしてデータを記述することもできます。その場合は、表のデータを下記のプログラムのように記述し、(x, y) のマスを `table4[y][x]` のようにインデックスに __「y座標」、「x 座標」の順__ で値を指定して参照します。

インデックスの意味の順番が逆になったため、下記のプログラムの `print(table4[2][1])` では、(2, 1) ではなく、__(1, 2)__ のセルの中身を表示している点に注意して下さい。同様の理由で、`print(table4)` で表示される内容も変化します。

```python
table4 = [
    [1, 2, 3], # 0 行のデータ
    [4, 5, 6], # 1 行のデータ
    [7, 8, 9]  # 2 行のデータ
]
print(table4[2][1])
print(table4)
```
実行結果
```
8
[[1, 2, 3], [4, 5, 6], [7, 8, 9]]
```

どちらの順番を採用しても __正しくデータを表現__ できますが、それぞれ以下のように利点と欠点があります。どちらを採用するかはプログラムの作成者が __自分で決める__ 必要がありますが、__その順番を後で忘れないように注意して下さい__。順番を勘違いしてプログラムを記述すると、思わぬ __エラーの原因__ になってしまうからです。

:::note warn
2 次元以上の配列を表す list をプログラムで記述する場合は、__インデックスの順番と意味__ を __意識しながら__ プログラムを記述することが重要です。

インデックスの順番と意味が分かりづらいと思った場合は、プログラムの分かりやすい場所などにコメントで list のインデックスの意味と順番を書いておくと良いでしょう。
:::

|  | 利点 | 欠点 |
|:-:|:--|:--|
|x、yの順   | 座標の順番が数学で使われる (x, y) の記法と同じなので直観的で __わかりやすく、間違えにくい__  | table3 のようにデータを記述した場合、列と行のデータが逆になっているように見えるので直観的にわかりづらい[^7]  |
|y、xの順   | table4 のようにデータを記述した場合、見た目が直観的にわかりやすい  | 座標の順番が数学の記法と逆なので __わかりづらく、間違えやすい__ |

:::note warn
本記事では数学の記法に従ったほうがわかりやすいと思いましたので、「x座標」、「y座標」の順でインデックスの意味を表すことにします。
:::

# 本記事で入力したプログラム

以下のリンクから、本記事で入力して実行した JupyterLab のファイルを見ることができます。

https://github.com/ysgeso/marubatsu/blob/master/004/marubatsu.ipynb

# 次回の記事

https://qiita.com/ysgeso/items/0d64d1ddba1982b5a5d3

[^1]:「要素番号」、「添え字」、「オフセット（offset）」と呼ぶ場合もあります
[^2]:本記事では array を利用しないので、array の説明は割愛します
[^3]:numpy は非常に便利なので、今後の記事で実際に利用します
[^4]:3 つの識別子を使う配列を 3 次元配列と呼びます。同様に 4 次元配列や 5 次元配列など、任意の次元の配列があります
[^5]:col は「列」を表す column の略です
[^6]:table は、英語で表の事を表します
[^7]:実際には table3 のような形で、2 次元配列のデータをすべてプログラムで直接記述することはあまりないと思いますので、この欠点はあまり気にする必要はないかもしれません