リスト

教科書 Lesson 5

これ以降は、教科書の Lesson 5 を進めてください。ただし 5.1〜5.3 まで、です。それが済めばすぐ次にある「確認課題」の 1. 2. に進んでください。

5.1 コレクション

(ここは概念説明のみ)

5.2 リストの基本

教科書 p.96 から、節ごとに重要なことが出てきます。一つずつ読み進めて下さい。

リストの仕組みを知る

p.96 に「リスト」「要素(element)」「変更可能(mutable、変更不可能 immutable も)」などの用語が出ています。あなた方の専門である計算機科学の専門用語です。覚えて下さい。

リストを作成する

p.97 からは実際に手を動かして試しながら読み進めて下さい。すべてインタラクティブモードで Python を起動して試すことができます。

>>> sale = [80, 60, 22, 50, 75]
>>> print(sale)
[80, 60, 22, 50, 75]
>>> 

リストの各要素の値を取得する

p.99 から読み進めて下さい。要素番号のことを「インデックス」または「添字(そえ字)」と呼びます。

教科書では print( ) 関数を使って変数の中身を出していますが、インタラクティブモードでは以下のように変数名をそのまま指定する方法もあります。

>>> sale = [80, 60, 22, 50, 75]
>>> sale[0]
80
>>> sale[1]
60
>>> 

リストを繰り返し文で扱う

p.101 から読み進めて下さい。for 文を使っていますが、これもインタラクティブモードで試すことができます。ちょっと操作に慣れないといけませんが。

>>> for s in sale:
...     print(s)    <<< インデントをちゃんとつけないといけません
...                 <<< 行の左端で Enter キーを入力すると実行が始まります
80
60
22
50
75
>>> 

5.3 リストの操作

p.103 から読み進めてください。これもインタラクティブモードで試しながら進んでください。

確認課題

準備

Lesson 4 の 4.5 while 文の課題2.「合計ではなく平均を得る」を思い出してください(見返してください)。それと同じように、リストの各要素を調べて、最低点・最高点・平均点を求めて下さい。これは Lesson 5 (p.136) の練習の1.にほぼ同じです。以下にプログラムの最初の一行と実行結果を示します。プログラムの続きを作って完成させて下さい。

points = [8, 10, 35, 14, 40, 20]
最高点は 40 です。

参考として、最高点を得るアルゴリズムを擬似コードで示します。

最高点候補を points[0] にする
変数 i を 1 から 5 まで変化させながらループする
    もし points[i] が最高点候補より大きければ最高点候補を points[i] にする
最高点候補を出力する

ところでループ制御を for p in points: のように書いて、得られた p を最高点候補と比較することでも動作はします。しかしその場合ループによる最初の p との比較が points[0] つまり「同じ値」となります。必ず「無駄な比較」を一回行うという意味で、できれば避けたいアルゴリズムですね。

課題1.

上で作ったプログラムを修正して、リストの要素の値が 0 の場合、それを無視して計算するようにしてください。以下にプログラムの最初の一行と実行結果を示しておきます。その続きを作ってプログラムを完成させて下さい。なおデータとして与えられる点数は 0 から 100 まで、またリストの中には 0 以外の値が一つ以上あるものとします。

points = [8, 0, 35, 14, 40, 20]
最高点は 40 です。
最低点は 8 です。
平均点は 23.4 です。

ところで「先頭の要素が0だった」場合、上の「準備」で用いた「最高点候補の初期値に points[0] をセット」して「それ以降の要素と比べる」という方法は正しく機能しません。このような場合は最高点候補の初期値に「入力としてあり得る最も小さな値をセット」して「すべての要素と比べる」のが良いでしょう。

以下のことに注意をして作ってください。

課題2.

リスト中の要素を見て、負の数があった場合はそれを含まないリストを、元のリストとは別に作って下さい。元のリストの要素を一つずつチェックして、該当する要素だけを新しいリスト(初期状態は空リスト)に append( ) していけば良いはずです。

image-20231106112756217

以下にプログラムの最初の二行を示しておきます。その続きを作ってプログラムを完成させて下さい。

list1 = [21, -6, 56, 11, -8, 34]
list2 = []

基本的なリスト操作のおさらいと補足

これでひとまず基本的な操作ができるようになったと思います。ざっとおさらい、あるいは教科書であまり説明されていない事項について説明しておきます。

添字の範囲を超えたアクセス

要素番号(添字)が「存在しない」ものを指すと、以下のようなエラーが出ます。「list index out of range」ですから、読めば意味がわかりますね。なお p.101の一番上に「インデックスの範囲」として、要素番号が「ゼロ」から「リストの長さ(要素の個数)-1 」であることが書かれています。

>>> data = [ 10, 20, 30 ]
>>> len( data )
3
>>> data[2]
30
>>> data[3]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
IndexError: list index out of range
>>> 

ところが面白いことに、.insert( ) は範囲を超えた位置を指定してもエラーとならず、できるだけそれに近い動きをしようとします。何故なんでしょうね。

負の添字

要素番号はリストの先頭を 0 番めの要素として数えますが、リストの末尾から数えることもできます。その場合は下の図のように、最後の要素を -1 番目の要素として数えます。

image-20240215123029774

>>> data = [1, 2, 3, 4, 5]
>>> data
[1, 2, 3, 4, 5]
>>> data[0]
1
>>> data[-1]
5
>>>

もちろん、範囲外の要素、例えば -6 番目を参照するとエラーになります。

同じ値(例えば 0 )が複数並んだリストを作成する

教科書では出てこないのですが、要素の個数を指定してリストを作成する方法があります。例えば8個の要素でリストを用意する方法を以下に示します。初期値として 0 を与えています。

>>> data = [0]*8
>>> data
[0, 0, 0, 0, 0, 0, 0, 0]
>>> len(data)
8
>>> data[4]=99
>>> data
[0, 0, 0, 0, 99, 0, 0, 0]
>>> 

つまり data = [9]*100 とすれば 100 要素の 9 からなるリストが生成されます。

メソッドと関数

一般的なプログラミング言語において「関数」はとても馴染みのあるものです。教科書でも p.100 にリストの長さを得る「 len( ) 」関数が紹介されています。ところで「 .append( ) 」のように、リスト変数の後ろに「 . (ドット)」でつないだものもありますが、それを「メソッド」と呼ぶ、と p.106 にはあります。一般的な関数やオブジェクト指向に関する基礎的な理解がないと、関数とメソッドの違いは分からないでしょう。ただ、とりあえず呼び出し方、作用する対象が違うのは分かると思います。つまり Python では関数は以下の二種類があります。

len( ) や input( ) など、標準的に使える関数の一覧はPythonドキュメントの「組み込み関数」にあります。メソッドは作用させる対象(リストや整数)ごとに用意されているものが異なるため、そのデータ型やオブジェクトごとのドキュメントを参照する必要があります。

「配列」との相違

C言語をはじめ多くの言語には「配列」と呼ばれるリストに似た仕組みがあります。しかし逆に Python の言語仕様には配列がありません。基本的に他の言語で配列で処理してきた事は Python ではリストを利用することになると思います。

【おまけ:参考】del 文による変数の削除

p.108に del 文によってリスト変数ごと消去できることが書かれています。リスト変数に限らず、普通の変数も同じように削除できます。通常、使われなくなった変数の削除は Python ではガベージ・コレクタが行います。しかし明示的に(積極的に)削除する機能も用意されています。

>>> data = [ 10, 20, 30 ]
>>> data
[10, 20, 30]
>>> del data     <<< 削除
>>> data
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'data' is not defined   <<< 未定義、と言われた
>>> a = 10  <<< リスト変数ではなく通常の変数
>>> del a   <<< 同様に削除
>>> a
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
NameError: name 'a' is not defined   <<< 未定義、となる
>>>