コンピュータ演習II 第05回 リスト¶

この回では、複数の値を 1 つにまとめて扱う リスト を学びます。これまでは 1 つの変数に 1 つの値を入れてきましたが、リストを使うと、たくさんの値をひとまとめにして管理できます。リストはこの先の回(繰り返し処理や整列・探索のアルゴリズム)でずっと使い続ける、とても大事な道具です。 これまでと同じように、Colab で実際にコードを書いて実行しながら読み進めてください。

1. リストとは¶

1.1 複数の値をまとめる¶

たとえば、5 人分のテストの点数を変数に入れることを考えます。これまでのやり方だと、点数の数だけ変数を用意することになります。

In [1]:
score0 = 90
score1 = 98
score2 = 85
score3 = 72
score4 = 63
print(score0, score1, score2, score3, score4)
90 98 85 72 63

これでも動きますが、点数が 100 人分あったら変数を 100 個も用意することになり、とても大変です。 そこで Python には リスト というしくみが用意されています。次のように書くと、5 つの値をまとめて 1 つの変数scores に入れられます。

In [2]:
scores = [90, 98, 85, 72, 63]   # 5 つの値をまとめて scores に入れる
print(scores)
[90, 98, 85, 72, 63]

[90, 98, 85, 72, 63] のように、値を 四角かっこ[ ] でくくり、それぞれを カンマ(,) で区切ったものがリストです。リストの中の 1 つ 1 つの値を 要素 と呼びます。たとえば「リストscores の要素」といえば、scores の中の値(90 や85 など)のことを指します。 リストを使うと、このように複数の値をまとめて 1 つの変数で管理できます。

リスト scores = [90, 98, 85, 72, 63] の各要素に 0 から 4 の番号が振られた図。先頭の 90 が 0 番目、63 が 4 番目

図のように、リストの要素には先頭から順に 番号 が振られています。この番号についてはこのあと2. でくわしく学びます。

要素を 1 つも持たないリストを作ることもできます。[ と] だけを並べて書きます。

In [3]:
empty_list = []   # 要素が何もないリスト
print(empty_list)
[]

このような要素を持たないリストを 空のリスト と呼びます。これは「これから値を 1 つずつ増やしていく」ような場面で、最初の入れ物として使います(要素の追加は4. で学びます)。

練習: 自分のリストを作ってください¶

好きな変数名で、好きな数値を 3 つ以上入れたリストを作り、print で表示してください。あわせて、空のリストも 1 つ作って表示してください。

In [4]:
# 好きな数値を入れたリストを作って print で表示してください


# 空のリストを作って print で表示してください

2. 要素へのアクセス¶

2.1 インデックス(要素の番号)¶

リストの中の特定の要素を取り出すことを、要素に アクセスする といいます。アクセスするには、要素の 番号 を使います。 ここで 1 つ、プログラム特有の大事なルールがあります。

自然数は 1 から始まりますが、プログラムでは 0 を始まりとして数える ことがほとんどです。たとえば文字列

"Hello"

の"H" は、ふつうの数え方では先頭から 1 番目の文字ですが、プログラムでは 0 番目 の文字と考えます。0 から数えるので、"o" は 5 番目ではなく 4 番目 の文字になります。

文字列 Hello の各文字に 0 から 4 の番号が振られた図。先頭の H が 0 番目、o が 4 番目

リストの要素の番号も、まったく同じく 0 から始まります。この番号を インデックス と呼びます。 リストscores のインデックス0 の要素にアクセスするには、scores[0] と書きます。

In [5]:
scores = [90, 98, 85, 72, 63]
print(scores[0])   # scores の 0 番目の要素にアクセスして表示
90

scores の 0 番目の要素は90 なので、90 が表示されます。同じように、scores[1] と書けば 1 番目の要素(98)にアクセスできます。ここで大事なのは、インデックスは 1 ではなく 0 から始まる という点です。

インデックスには、数値そのものだけでなく、変数 を使うこともできます。

In [6]:
scores = [90, 98, 85, 72, 63]
index = 2          # index に 2 を入れる
print(scores[index])    # index は 2 なので、scores[index] は scores[2] になり、85 が表示される
85

scores[2] の2、scores[index] のindex のように、何番目の要素にアクセスするかを指定する部分を インデックス と呼びます。たとえばscores[1] のインデックスは1 です。

エラー事例: 範囲外の番号¶

要素が 5 つのリストだからといって、scores[5] のように書くとどうなるか試してください。

In [7]:
scores = [90, 98, 85, 72, 63]
print(scores[5])
---------------------------------------------------------------------------
IndexError                                Traceback (most recent call last)
Cell In[7], line 2
      1 scores = [90, 98, 85, 72, 63]
----> 2 print(scores[5])

IndexError: list index out of range

IndexError: list index out of range という赤いエラーが出ます。これは「リストのインデックスが範囲の外です」という意味です。 インデックスは 0 から始まるので、要素が 5 つのscores = [90, 98, 85, 72, 63] にはscores[0]、scores[1]、scores[2]、scores[3]、scores[4] の 5 つしかありません。scores[5] は存在しないのでエラーになります。 このIndexError は、これからリストを使うときに何度も出会うエラーです。出てしまっても落ち着いて、「インデックスが範囲外になっていないか」を確認すればだいじょうぶです。

リストインデックスの概念を理解したところで、フローチャートでも同じ scores リストを作成してみましょう。

フローチャートでリストを作る¶

Flowchart Maker では、変数・値ブロックに Python とまったく同じ式 を書くだけでリストを作れます。scores = [90, 98, 85, 72, 63] を1 つのブロックに書き、出力ブロックで scores を出力すると、リスト全体を確認できます。

No description has been provided for this image

2.2 要素を取り出して使う¶

リストの要素は、ふつうの値と同じように使えます。たとえば、要素を別の変数に代入できます。

In [8]:
scores = [90, 98, 85, 72, 63]
sc0 = scores[0]            # scores の 0 番目の要素を変数 sc0 に代入
print("scores[0]:", scores[0])
print("sc0:", sc0)
scores[0]: 90
sc0: 90

sc0 にはscores[0] の値90 が入ります。 さらに、要素は計算(演算)にも使えます。

In [9]:
scores = [90, 98, 85, 72, 63]
goukei = scores[0] + scores[1]      # 0 番目と 1 番目の要素を足す
nibai  = scores[2] * 2         # 2 番目の要素を 2 倍する
print("goukei:", goukei)
print("nibai:", nibai)
goukei: 188
nibai: 170

このように、リストの要素は取り出して別の変数に入れたり、足し算や掛け算などの計算に使ったりできます。

フローチャートで要素を取り出す・計算する¶

フローチャートでも、リストの要素を別の変数に取り出したり、計算に使ったりできます。たとえば scores[0] の値を変数 sc0 に取り出して出力するには、次のようにします。ラベル付きで出力するときは、Python と同じく print("sc0:", sc0) のようにカンマで区切ります(文字列と数値を + でつなぐことはできません。これも Python と同じです)。

No description has been provided for this image

要素を使った計算も同じです。goukei = scores[0] + scores[1]、nibai = scores[2] * 2 のように書けます。

No description has been provided for this image

Python と同じ考え方で、取り出した要素を別の変数に入れたり、計算に使ったりできます。

練習: 学籍番号でアクセスしてください¶

ここからの練習では、自分の 学籍番号後半 5 桁 を使います。練習は手を動かして慣れるための時間で、提出は不要です。気軽に試してください。

次のリストscores について、sid(学籍番号後半 5 桁)を5 で割った余りをインデックスindex にして、scores[index] を表示してください。余りはsid % 5 で求められ、0 から4 のどれかになります(ちょうどリストのインデックスの範囲です)。

In [10]:
scores = [90, 98, 85, 72, 63]
sid = 61250        # ← 自分の学籍番号後半 5 桁に書き換えてください
index = sid % 5        # 0〜4 のどれかになる

# scores[index] を表示してください

3. 要素の上書き¶

すでにある要素の値を、別の値に変えることを 上書き といいます。上書きは、ふつうの変数への代入と同じく イコール(=) で行います。scores[1] に新しい値を代入すると、もとの値が新しい値に置き換わります。

In [11]:
scores = [90, 98, 85, 72, 63]
print("上書き前:", scores)
scores[1] = 100          # 1 番目の要素を 100 に上書きする
print("上書き後:", scores)
上書き前: [90, 98, 85, 72, 63]
上書き後: [90, 100, 85, 72, 63]

プログラムは 上から順に 1 行ずつ 実行されます。scores[1] = 100 の行で、もともとscores[1] にあった98 が消え、100 に置き換わります。これが上書きです。 ここで注意です。scores = [90, 98, 85, 72, 63](要素は 5 つ)の 後ろに新しい要素を増やそう として、scores[5] = 50 と書くとどうなるか試してください。

In [12]:
scores = [90, 98, 85, 72, 63]
scores[5] = 50
---------------------------------------------------------------------------
IndexError                                Traceback (most recent call last)
Cell In[12], line 2
      1 scores = [90, 98, 85, 72, 63]
----> 2 scores[5] = 50

IndexError: list assignment index out of range

またIndexError が出ます。scores にはもともとscores[5] が存在しないため、そこに代入することはできません。 つまり、イコールでできるのは、すでにある要素の上書きだけ です。イコールで新しい要素を増やすことはできません。要素を増やす方法は、次の章で学びます。

フローチャートで要素を上書きする¶

フローチャートでも、scores[1] = 100 のように変数・値ブロックで書けば、すでにある要素を上書きできます。実行すると、上書きの前後でリストの中身が変わることが確認できます。

No description has been provided for this image

Python と同じく、すでにある要素はイコールで上書きできます。

練習: 要素を上書きしてください¶

リストscores の、sid % 5 番目の要素を0 に上書きし、上書きしたあとのリスト全体をprint で表示してください。

In [13]:
scores = [90, 98, 85, 72, 63]
sid = 61250        # ← 自分の学籍番号後半 5 桁に書き換えてください
index = sid % 5

# scores[index] を 0 に上書きして、scores 全体を表示してください

4. 要素の追加(append)¶

リストの後ろに新しい要素を追加するには、append を使います。書き方は次のとおりです。

リストの変数名.append(追加したい値)
In [14]:
scores = [90, 98, 85, 72, 63]
print("追加前:", scores)
scores.append(50)        # scores の一番後ろに 50 を追加する
print("追加後:", scores)
追加前: [90, 98, 85, 72, 63]
追加後: [90, 98, 85, 72, 63, 50]

scores の一番後ろに50 が追加され、[90, 98, 85, 72, 63, 50] になりました。 scores.append(50) のように、リスト名 のあとに .append(...) と書くのが、これまでにない新しい形です。append のような「値に対して使う命令」を メソッド と呼びますが、いまはprint やlen(次に学びます)と同じ仲間の命令だと考えてかまいません。

append は何度でも使えます。1 回使うごとに、後ろに 1 つずつ要素が増えていきます。

In [15]:
scores = [90, 98, 85]
scores.append(72)
print(scores)
scores.append(63)
print(scores)
scores.append(50)
print(scores)
[90, 98, 85, 72]
[90, 98, 85, 72, 63]
[90, 98, 85, 72, 63, 50]

前章で学んだとおり、イコールでは要素を増やせませんでした。要素を新しく増やすときはappend、すでにある要素を変えるときはイコール と覚えておきましょう。

Flowchart Maker でも、scores.append(50) のように Python と同じ書き方 で要素を追加できます(変数・値ブロックの変数欄を空にして、値の欄に式をそのまま書きます)。

No description has been provided for this image

なお、C 言語などの低水準な言語の配列は、定義した時点で長さが決まる 固定長 で、append にあたる機能はありません。Python をはじめ多くの言語には後から長さを伸ばせる動的なリストがあり、append はそのための便利な機能です。固定長と「現在の長さ」を意識する考え方は、後半で学ぶ整列(ソート)や探索のアルゴリズムでも土台になります。

練習: 要素を追加してください¶

空のリストscores = [] を作り、append を使って、sid を10 で割った余り(sid % 10、学籍番号の 1 の位)を 1 つ追加してください。追加したあとのリストをprint で表示してください。

In [16]:
scores = []
sid = 61250        # ← 自分の学籍番号後半 5 桁に書き換えてください

# sid % 10 を append で scores に追加して、scores を表示してください

5. リストの長さ(len)¶

リストには 長さ という考え方があります。これは、リストがいくつの要素を持っているか、という意味です。たとえばscores = [90, 98, 85, 72, 63] の長さは5 です。 要素の数が多いと、人が目で数えるのは大変ですし、間違えることもあります。そこで、リストの長さを自動で求める len という命令を使います。

In [17]:
scores = [90, 98, 85, 72, 63]
print(len(scores))      # scores の長さ(要素の数)を求めて表示
5

scores の要素は 5 つなので、5 が表示されます。len(リストの変数名) と書けば、長さが求められます。長さは別の変数に入れることもできます。

In [18]:
scores = [90, 98, 85, 72, 63]
nagasa = len(scores)
print(nagasa)
5

append で要素を追加すると、長さも変わります。

In [19]:
scores = [90, 98, 85, 72, 63]
print("長さ:", len(scores))
scores.append(50)
print("長さ:", len(scores))
長さ: 5
長さ: 6

len を使うと、リストの 一番後ろの要素 にアクセスできます。インデックスは 0 から始まるので、長さが5 のリストの一番後ろの要素はscores[4]、つまりscores[len(scores) - 1] です。

In [20]:
scores = [90, 98, 85, 72, 63]
saigo = scores[len(scores) - 1]      # len(scores) は 5 なので scores[4]、一番後ろの要素
print("一番後ろの要素:", saigo)
一番後ろの要素: 63

リストの長さがいくつであっても、scores[len(scores) - 1] と書けば必ず一番後ろの要素にアクセスできます。これは今後よく使う書き方です。

フローチャートでリストの長さを求める¶

フローチャートでも、リストの長さは Python と同じ len(scores) で求められます。scores の要素は 5 つなので、len(scores) は 5 になります。

No description has been provided for this image

一番後ろの要素にアクセスするときも、scores[len(scores) - 1] のように書けます。

練習: 長さを求めてください¶

リストscores に、append を使ってsid % 10(学籍番号の 1 の位)を 1 つ追加してください。そのうえで、追加後のscores の 長さ と、一番後ろの要素(scores[len(scores) - 1])を表示してください。

In [21]:
scores = [90, 98, 85, 72, 63]
sid = 61250        # ← 自分の学籍番号後半 5 桁に書き換えてください

# sid % 10 を append で追加してください


# 追加後の scores の長さと、一番後ろの要素を表示してください

6. 演習: 学籍番号でリストを操作する¶

最後に、この回で学んだことを組み合わせた演習です。次のリストscores と、自分の学籍番号後半 5 桁sid を使います。順番に取り組んでください。

In [22]:
scores = [90, 98, 85, 72, 63]
sid = 61250        # ← 自分の学籍番号後半 5 桁に書き換えてください
index = sid % 5        # 0〜4 のインデックス
  1. scores[index] を表示する(アクセス)。
  2. scores[0] とscores[index] を足した値を表示する(要素を使った演算)。
  3. scores[index] を100 に上書きしてから、scores 全体を表示する(上書き)。
  4. scores の後ろにsid % 10 をappend で追加してから、scores の長さを表示する(追加と長さ)。

それぞれ別のセルに書いて、実行して確かめてください。うまく動いたら、sid の値をいろいろ変えて、表示される結果が変わることも確かめましょう。

In [23]:
scores = [90, 98, 85, 72, 63]
sid = 61250        # ← 自分の学籍番号後半 5 桁に書き換えてください
index = sid % 5

# 1〜4 を順番に書いてください

まとめ¶

この回では、複数の値をまとめて扱う リスト を学びました。

  • リスト:値を四角かっこ[] でくくり、カンマ, で区切ってまとめたもの。1 つ 1 つの値を 要素 と呼ぶ。
  • インデックス:要素の番号。0 から始まる。scores[0] で 0 番目の要素にアクセスする。範囲外の番号を使うとIndexError になる。
  • 上書き:scores[1] = 100 のように、イコールですでにある要素を変える。イコールでは新しい要素を増やせない。
  • 追加(append):scores.append(値) で、後ろに新しい要素を増やす。
  • 長さ(len):len(scores) で要素の数を求める。一番後ろの要素はscores[len(scores) - 1]。

リストは、次回からの繰り返し処理や、後半のアルゴリズム(整列・探索)でずっと使い続けます。インデックスが 0 から始まることと、IndexError の意味を、ここでしっかりおさえておきましょう。