
武蔵野個別指導塾の特徴
【情報I】プログラミングの基礎③を図解で総まとめ—配列(リスト)・関数・引数と戻り値|武蔵野個別指導塾

リストの添字、合計の更新、最大値を返す関数を3つの図と例題でたどり、引数と戻り値の流れを練習問題で確かめましょう。
よくあるのは、コンビニのイートインで情報のノートを開き、リストに並ぶ3つの数は読めるのに、「2番目を取り出す」となると角括弧の中に何を書けばよいか止まってしまうという場面です。さらに、そのリストが関数の丸括弧に入ると、数がどこへ渡り、計算結果がどこへ戻るのかが見えなくなります。値そのものは小さくても、値の置き場所と処理の順番を同時に追う必要があるためです。
この単元では、複数の値をひとまとまりに扱うリストと、ひとまとまりの処理に名前を付ける関数を学びます。出発点は「何番目か」と「添字はいくつか」を分けることです。そこから、合計や最大値を1つずつ更新する方法、入力を引数として渡して結果を戻り値で受け取る方法へ進みます。記号を丸暗記するのではなく、手元の紙に値の移動を書きながら、プログラムの出力を自分で説明できるようにしましょう。
この単元で身につけること
- リストを作り、必要な要素を取り出します。角括弧の中に値を並べる書き方と、添字を使って1つの要素を指定する書き方を区別します。
- 要素の個数と添字の範囲を対応させます。要素が3個なら、先頭から順に使う添字は0、1、2であり、個数の3をそのまま末尾の添字にはしません。
- 合計と最大値を繰り返しで求めます。途中結果を入れる変数を準備し、各要素を調べた後で何が保存されているかを言葉にします。
- 関数を定義し、必要な場所で呼び出します。定義しただけでは関数の本体が実行されないことを、処理の順番と結びつけて理解します。
- 引数と戻り値を使って処理をつなぎます。画面への表示と呼び出し元への返却を区別し、別のデータにも同じ処理を適用できる形にします。
これまでに学んだ変数への代入、条件分岐、繰り返しを、リストというデータのまとまりに対して使うのが今回のつながりです。特に、代入の右辺を先に計算することと、字下げで処理のまとまりを表すことを思い出すと、途中の値を追いやすくなります。
基本の考え方
リストは値の並び、添字は位置を指定する番号です
配列は、複数の要素を順序付きでまとめ、添字によって要素を扱うためのデータ構造です。Pythonでは、情報Iで配列の考え方を学ぶ際にリストをよく使います。ただし、すべての言語の配列とPythonのリストが細部まで同じ仕組みというわけではありません。Pythonのリストには、要素数を後から変えられるなどの性質があります。まずは共通する「順番を持つ要素の集まり」という考え方を押さえます。
たとえば、3つの品物の個数を12、8、15と並べるとき、リストは [12, 8, 15] と表せます。1つずつの値が要素で、要素は3個です。この並びを counts という変数で扱うなら、counts[0] が12、counts[1] が8、counts[2] が15を指します。変数名はリストを扱うための名前、角括弧の中は要素の位置を指定する番号と読み分けます。
図1のように、先頭の添字は0です。「2番目の要素」と言われたら、先頭から2個目なので添字は1になります。日常語の順番を表す数と、プログラムの添字が1ずれることを、毎回頭の中だけで処理しようとしないでください。慣れるまでは、要素の上に添字を書き添える方法が確実です。

図1の3つの枠は、コンピュータ内部の物理的な配置そのものを表す図ではありません。値と位置の対応を読むための図です。len(counts) は要素の個数である3を返しますが、0から始める添字の最後は2です。一般に、要素数が n の空でないリストについて、0から順に指定する添字は0から n − 1までになります。Pythonには負の添字もありますが、ここではまず0以上の添字で位置を確かめます。
要素を変更するときは、たとえば counts[1] = 10 と書きます。これは2番目の値を10に置き換える操作で、要素を1個追加する操作ではありません。その結果、並びは [12, 10, 15] となり、個数は3のままです。また、同じ値が複数回現れても、位置が異なれば別の要素として数えます。[5, 5, 2] の要素数も3です。
合計と最大値は、途中結果の意味から考えます
リストの合計は、最初に合計用の変数を0にしてから、要素を1つずつ足して求められます。0にするのは、まだ何も足していない状態の合計が0だからです。total = total + value という代入では、右辺の「これまでの合計に今回の値を足す」を先に計算し、その結果を左辺の total に保存します。数学の等式として両辺を変形するのではなく、値を更新する命令として読みます。
最大値の場合は、途中結果の意味が変わります。保存しておくのは合計ではなく、「ここまでに調べた要素の中でいちばん大きい値」です。次の要素のほうが大きければ更新し、小さいか等しければそのままにします。最初の候補に先頭の要素を使えば、すべての要素が負でも正しく比較できます。
この違いは初期値にも表れます。合計の初期値は0でよい一方、最大値の候補をいつも0にすると、負の値だけのリストで誤ります。最大値を求める前には、リストが空でないことも必要です。空のリストには先頭の要素がなく、最大値として選べる要素もありません。何を受け付ける処理なのかを先に決めることが、正しいプログラムの条件になります。
関数は入力と結果の役割を決めた処理のまとまりです
関数を定義するには def を使い、関数名、丸括弧、コロンを書いてから、本体を字下げして書きます。定義時の丸括弧に書く名前は、渡された値を関数の中で受け取るための名前です。関数名の後に丸括弧を付けて呼び出すと、本体の処理が実行されます。単に関数の名前を決めただけでは、計算はまだ始まりません。
呼び出す際に渡す値を引数といいます。定義側で受け取る名前を仮引数、呼び出し側で渡す値や式を実引数と呼び分けることもあります。たとえば largest(values) という形で定義された関数に対し、largest([-4, -7, -2]) と呼び出すなら、values は受け取り側の名前で、[-4, -7, -2] は渡すリストです。両者の変数名が同じでなければいけない、という決まりはありません。
return で呼び出し元へ返した値が戻り値です。呼び出し全体を1つの式として見ると、その位置で戻り値を使えます。result = largest([-4, -7, -2]) なら、返された最大値が result に代入されます。これに対して print は画面に表示するための関数です。画面に数字が出たことと、その数字を自作関数が呼び出し元へ返したことは、別に確かめる必要があります。
関数の利点は、長い処理を短い名前で呼べることだけではありません。入力を変えて同じ処理を使い、処理の意味を1か所にまとめ、修正したときに確かめる範囲を整理できます。合計を計算する部分と結果を表示する部分を分ければ、同じ合計を画面に出すほか、平均の計算などにも使えます。このように役割ごとに処理を分けることを部品化といいます。
例題で解き方を確かめる
例題1 添字を使って要素を読み、変更します
次のプログラムの出力を求めます。print にカンマで複数の値を渡すと、ここでは値の間に空白が入り、1行に表示されます。リスト全体を表示する最後の行と、個別の要素を表示する最初の行を区別しましょう。
counts = [12, 8, 15]
print(counts[0], counts[2])
counts[1] = counts[1] + 2
print(counts)
- 最初のリストに添字0、1、2を対応させます。取り出す位置を確定してから値を見るためです。counts[0] は12、counts[2] は15になります。
- 更新する行の右辺を、変更前の状態で計算します。counts[1] は8なので、8 + 2で10です。右辺の値が決まってから、添字1の要素だけを10に置き換えます。
- 最後にリスト全体を読み直します。変更していない先頭の12と末尾の15は残り、並びは [12, 10, 15] です。代入の対象が1つの要素だったことを確認します。
出力は次のとおりです。
12 15
[12, 10, 15]
答え:1行目は「12 15」、2行目は「[12, 10, 15]」です。
例題2 合計の変化を順番に追います
次のプログラムについて、繰り返しの各回が終わった後の total と、最後の出力を求めます。for value in counts は、counts の要素を先頭から1つずつ value に受け取って処理する書き方です。value に入るのは添字ではなく要素の値です。
counts = [12, 8, 15]
total = 0
for value in counts:
total = total + value
print(total)
- 繰り返しに入る前の total を0と記録します。まだ要素を足していない状態を出発点にすると、最初の更新を見落としません。
- value に12、8、15を順番に入れて更新します。各回では1つ前の合計を使うため、total は12、20、35と変わります。毎回0から足し直すのではありません。
- print の字下げを確かめます。ここでは for と同じ深さにあるため、3回の繰り返しがすべて終わってから1回だけ表示します。途中の12と20は画面には出ません。
図2のように、更新前と更新後を矢印でつなぐと、その回で足した要素を区別できます。繰り返しが正しく進むかを見るには、「各回の終了時に、処理済みの要素の合計が total に入っている」という意味が保たれているかを確かめます。

図2の最後は35ですが、これは要素数ではありません。3個の要素の値を足した結果です。変数の名前だけを見ずに、何を保存している変数なのかを表に書くと、個数を数える処理との混同を防げます。
| 処理した要素 | 更新前の total | 更新後の total |
|---|---|---|
| 12 | 0 | 12 |
| 8 | 12 | 20 |
| 15 | 20 | 35 |
出力は次のとおりです。
35
答え:各回の total は12、20、35で、出力は35です。
例題3 最大値を返す関数を読みます
次の largest は、空でない数値のリストから最大値を返す関数です。負の値だけのリストを渡したときの出力を求めます。関数の入力条件を満たしているか確かめてから、本体の比較を追いましょう。
def largest(values):
best = values[0]
for value in values:
if value > best:
best = value
return best
result = largest([-4, -7, -2])
print(result)
- 呼び出し元から渡すリストを確認します。values は [-4, -7, -2] を受け取り、先頭の値があるので best = values[0] を実行できます。最初の候補 best は −4です。
- 各要素と候補を比べます。最初の −4は候補と等しいので更新せず、次の −7も −4より小さいので更新しません。最後の −2は −4より大きいため、候補を −2に変えます。
- for の終了後に return best を実行します。すべての要素を調べた候補を返す必要があるため、return は繰り返しの外側に置いてあります。戻り値 −2が result に代入されます。
- 呼び出し元の print を実行します。関数の計算が終わってから表示することで、結果を受け取る処理と画面に出す処理を分けて読めます。
この書き方では先頭の要素を初期値にし、繰り返しでも先頭から調べています。最初の比較は同じ値どうしなので更新は起きませんが、結果は正しく求まります。先頭を二度見たから二度足される、ということもありません。ここで行っているのは加算ではなく、候補と比較して必要なときだけ置き換える処理だからです。
出力は次のとおりです。
-2
答え:最大値は −2で、result に入る値も出力も −2です。
つまずきやすいところと直し方
要素の個数を末尾の添字にしてしまいます
誤った書き方は、3要素の counts の末尾を counts[3] と指定することです。どこが違うかというと、3は個数であり、0、1、2と並ぶ添字の中に3はありません。このリストで counts[3] を読み取ろうとすると、範囲外の要素を指定したことになり、IndexError が発生します。値が0になるわけでも、最後の要素を自動で選ぶわけでもありません。
正しい書き方は、この場合なら counts[2] です。空でないリストの末尾を個数から指定するなら counts[len(counts) – 1] と書けます。問題で添字の始まりが別に定められている場合はその定義を読み、Pythonの0始まりを無条件に持ち込まないようにします。最初に「先頭と末尾の有効な添字」を紙に記すだけでも、範囲外の読み取りを見つけやすくなります。
最大値の候補を必ず0から始めてしまいます
誤った書き方は、どんな数値のリストでも最大値用の best を0で初期化することです。どこが違うかは、例題3の [-4, -7, -2] を当てはめるとはっきりします。どの要素も0より大きくないため、一度も候補が更新されず、リストに含まれていない0を最大値としてしまいます。
正しい書き方は、空でないことを条件に、best = values[0] とすることです。こうすれば最初から候補は実際の要素であり、負の値だけでも比較が成り立ちます。合計の0は「何も足していない合計」を表せますが、最大値の0には「まだ調べていない最大値」という意味をいつでも持たせられるわけではありません。初期値は覚える数字ではなく、途中結果の意味から選ぶ値です。
表示した値がそのまま戻り値になると思ってしまいます
誤った書き方は、最大値を返すつもりで関数の末尾を print(best) だけにし、return を書かないことです。どこが違うかというと、print は表示を行う一方、best を呼び出し元の式の値として返す指示にはならない点です。Pythonでは、return による値の返却がないまま関数の終わりまで実行すると、その呼び出しの戻り値は None になります。
正しい書き方は、関数の末尾で return best とし、必要に応じて呼び出し元で print(result) とすることです。図3のように、引数は呼び出し元から関数へ渡り、戻り値は関数から呼び出し元へ返ります。その後の表示は、戻り値を受け取った側が選べる操作です。

図3の戻り矢印をたどると、「結果を計算した場所」と「その結果を使う場所」が区別できます。なお、return を実行すると、その時点でその関数の呼び出しは終了します。例題3で return を繰り返しの中へ入れると、最初の要素しか調べずに帰ってしまいます。return の有無だけでなく、すべての比較が終わる位置にあるかも確認してください。
練習問題
練習1 変更される位置を確かめます
次の出力を求め、代入で変更されるのが何番目の要素かも答えてください。右辺に現れる位置と、左辺で変更する位置を分けて考えます。
items = [6, 3, 9, 2]
items[2] = items[0] + items[3]
print(items[2], len(items))
練習2 合計の関数を2回使います
次の2行の出力を求めてください。2回目の呼び出しで、1回目の合計が残るかどうかも説明します。[] は要素が1個もない空のリストです。
def total_of(values):
total = 0
for value in values:
total = total + value
return total
print(total_of([5, 0, 7]))
print(total_of([]))
練習3 最大値が同じ要素を含む場合を考えます
次の出力と、best = value による更新回数を求めてください。最初の best = values[0] は初期化とし、更新回数には数えません。
def largest(values):
best = values[0]
for value in values:
if value > best:
best = value
return best
print(largest([4, 9, 9, 3]))
答えと解説
練習1の出力は次のとおりです。
8 4
右辺は6 + 2で8になり、添字2、つまり3番目の要素が9から8に変わります。リスト全体は [6, 3, 8, 2] で、要素の個数は4のままです。値を置き換えても要素の位置が増えるわけではないため、len(items) は変化しません。
練習2の出力は次のとおりです。
12
0
1回目の合計は5 + 0 + 7で12です。2回目も関数の本体の先頭から実行するので、total は改めて0に初期化されます。空のリストでは for の本体が一度も実行されず、そのまま0を返します。この total は関数の中で使うローカル変数で、前回の合計を引き継いで蓄積する仕組みにはなっていません。
練習3の出力は次のとおりです。
9
初期値は4です。各要素を見た後の候補は4、9、9、9となり、更新は最初の9に出会ったときの1回です。次の9は候補と等しく、条件の「より大きい」を満たさないので更新しません。最大値そのものを求めるだけなら、同じ最大値が複数あっても戻り値は9です。最大値の位置や登場回数を求める問題とは、保存すべき情報が違います。
次の単元へのつながりと家庭での確かめ方
リストを位置で指定し、値を順番に調べる考え方は、必要なデータを探す探索や、順番を並べ替える整列につながります。最大値の候補を更新する処理が読めれば、条件に合う要素を見つけて記録する処理にも進みやすくなります。関数として切り出すと、探索や整列の処理を別のリストにも適用でき、全体のプログラムを役割ごとに読む助けになります。
家庭では、次の2つを合わせて5分ほどで確かめられます。1つ目は、紙に4つの数を書き、その上に添字を書いてから、「3番目」「添字3」「要素数」をそれぞれ指すことです。2つ目は、例題3のリストを負の数3個に入れ替え、初期値、各回の候補、戻り値を順に書くことです。答えだけでなく、更新しなかった理由も1か所説明すると、比較の読み違いを見つけられます。
保護者の方がお子さまと確かめるなら、完成したコードを暗唱させるよりも、「今の候補はどれですか」と途中の値を尋ねると、止まった箇所が見えます。個別指導では、その箇所に応じて、添字と要素の対応、代入の右辺を先に読む手順、字下げの範囲まで戻って確認します。
まとめ
プログラムが長く感じられたら、次に実行する行と、その直前に保存されている値を1組ずつ取り出してみましょう。リストに並ぶ値、途中結果、関数から返る値が紙の上でつながれば、出力の予想には根拠が生まれます。うまく動かない場合も、「添字を選んだ時点」「候補を更新した時点」「呼び出し元に戻る時点」のどこで予想と違ったかを探せます。
引数として渡した値が戻り値になるまでを説明できれば、その関数は自分で確かめて使える部品です。
本気になった日が、入塾の日。
お子様の教育、迷ったら「丸投げ」してください。必ず、期待以上の結果で返します。武蔵野で育む、武蔵境で学ぶ。
電話は年中無休。365日、24時間、お電話可能。



