仮の宿 学習室

クラウド・AI・Python CLOUD / AI / PYTHON

制御構造とデータ構造

講義 4 本・確認問題 40 問 | 本試験では「Python3基礎」(0問)の一部 | 最終更新 2026-09-24

この章で学ぶこと
目次
  1. 制御構造 if for while と else 節
  2. 反復の道具 enumerate zip 内包表記
  3. リストとタプル 変わるものと変わらないもの
  4. 辞書と集合 キーで引く入れ物
  5. 確認問題(40問)
  6. 演習ツール

1. 制御構造 if for while と else 節

条件で分ける if、繰り返す for と while、そして Python 独特の for/else。break と continue と pass の使い分けまで、処理の流れを操る道具が一通り分かります。

プログラムは書いた順に上から流れますが、それだけでは仕事になりません。条件によって道を分け、同じ処理を必要な回数だけ繰り返す。この2つを受け持つのが制御構造です。Python の分岐は if で始まり、途中の条件は elif、どれにも当てはまらない場合は else に書きます。elif はいくつ並べてもよく、else は無くてもかまいません。上から順に判定され、最初に真になったブロックだけが実行されます。

条件に書けるのは真偽値だけではありません。Python は値そのものに真偽を持たせていて、0・空の文字列・空のリスト・空の辞書・None は偽として扱われ、それ以外はおおむね真です。ですから if len(items) > 0 と書かなくても if items で通じます。ここを知っていると、後で出てくる and と or の話がつながります。

for は「反復可能なものから1つずつ取り出して変数に入れる」文です。C言語のようにカウンタを自分で増やす形ではありません。回数を決めて回したいときは range を使います。range(stop) は 0 から stop の手前まで、range(start, stop) は start から stop の手前まで、range(start, stop, step) は step ずつ進みます。stop は含まれません。step に負の数を入れれば逆順になります。なお range が返すのはリストではなく range 型のオブジェクトで、必要な数をその都度作ります。中身を並べて見たいときは list() に通します。

while は条件が真である間だけ繰り返します。回数が決まっていないとき、たとえば入力が正しくなるまで聞き直すような場面に向きます。条件に使っている変数を本体の中で変え忘れると、いつまでも終わらないので注意してください。ループの中では break でループそのものを打ち切り、continue でその回の残りをとばして次の反復に進みます。何もしないことを明示したいときは pass を置きます。pass は構文上ブロックが必要なのに書くことがない場所の穴埋めで、break や continue のように流れを変える働きはありません。

ここからが Python 独特の話です。for と while には else 節を付けられます。この else は「条件が偽のとき」ではなく、「break されずにループが終わったとき」に実行されます。探し物をするループで、見つかったら break、最後まで見つからなければ else で見つからなかった旨を出す、という書き方が定番です。気をつけたいのは、反復の対象が空でも else は実行されるという点です。1回も回らなければ break もしていないのですから、Python の理屈では当然の帰結になります。逆に break で抜けたときだけ else はスキップされます。

比較演算子は数学の書き方のようにつなげられます。1 < x < 5 は (1 < x) and (x < 5) と同じ意味で、しかも x は1度しか評価されません。値を選ぶだけなら三項演算子も使えます。書き方は 真のときの値 if 条件 else 偽のときの値 で、条件が真ん中に来る並びに慣れておいてください。

最後に and と or です。この2つは True や False を返すのではなく、評価をやめた時点の値をそのまま返します。or は左から見て最初に真になった値を返し、最後まで真が無ければいちばん右の値を返します。and は逆に最初に偽になった値を返し、すべて真なら最後の値を返します。真偽が決まった時点で右側を評価しないので短絡評価と呼ばれ、name or 'ゲスト' のような既定値の書き方に使われます。

ループの抜け方と else 節が実行されるかどうか
ループの終わり方何が起きるかelse 節
条件が偽になって終わるループを正常に抜ける実行される
反復の対象が空だった本体が1回も動かない実行される
continue で最後まで回った各回の残りをとばしただけ実行される
break で抜けたループを途中で打ち切るスキップされる
scores = [80, 95, 60] for s in scores:    if s < 50:        print("赤点あり")        breakelse:    print("全員合格") # 50 未満が1つも無いので break されず、else が動いて 全員合格 が出る

用語

elif
else if の短縮形。いくつ並べてもよく、上から順に判定されて最初に真になったブロックだけが実行される。
range
整数の並びを表す組み込み型。range(start, stop, step) の stop は含まない。リストではないので、並べて見るときは list() に通す。
break
いま入っているループを打ち切って外に出る文。else 節が付いていても、break で抜けた場合はスキップされる。
continue
その回の残りの処理をとばして次の反復に進む文。ループ自体は続くので、else 節は通常どおり実行される。
pass
何もしない文。構文上ブロックが必要なのに書くことがないときの穴埋めに使う。流れを変える働きはない。
for/else
for に付ける else 節。break されずにループが終わったときに実行される。反復対象が空のときも実行される。
連鎖比較
a < b < c のように比較をつなげる書き方。and でつないだのと同じ意味になり、真ん中の式は1度しか評価されない。
三項演算子
値1 if 条件 else 値2 という形の式。条件が真なら値1、偽なら値2になる。文ではなく式なので、そのまま代入や引数に書ける。
短絡評価
and と or が、真偽が決まった時点で右側の評価をやめる仕組み。返るのは True や False ではなく、評価をやめた時点の値そのもの。

例題

例題:例題: while ループが条件で自然に終わったときだけ後片付けをしたい。break で抜けたときは何もしたくない。どう書くか。
答えと考え方 while の本体の後ろに else 節を付け、そこに後片付けを書きます。else はループが break されずに終わったときだけ実行されるので、break で抜けた回はスキップされます。フラグ変数を1つ用意して break の直前で立て、ループの後で if フラグ と書く方法もありますが、else 節を使えばその変数が要りません。while だけでなく for でも同じように書けます。
例題:例題: total = 0 or None or [] を評価すると、total には何が入るか。
答えと考え方 or は左から順に評価して、最初に真になった値を返します。0 も None も空のリストもすべて偽なので、真の値は1つも見つかりません。この場合はいちばん右の値がそのまま返るので、total には空のリストが入ります。True でも False でもない点が大事です。and と or は真偽値ではなく、評価をやめた時点の値を返します。

出典・根拠:Python Software Foundation「Python チュートリアル 4. その他の制御フローツール」Python 3.14 ドキュメント(2026年8月確認)

2. 反復の道具 enumerate zip 内包表記

番号を振る enumerate、2つを並べて回す zip、1行で新しい入れ物を作る内包表記。そして「イテレータは1回で尽きる」という落とし穴が分かります。

for でリストを回していると、要素と一緒に何番目かも欲しくなります。range(len(items)) を回して添字で取り出す書き方もできますが、Python では enumerate を使うのが普通です。enumerate は反復可能なものを受け取り、(番号, 要素) というタプルを次々に返します。for i, item in enumerate(items) と2つの変数で受けるのが定型です。番号は既定で 0 から始まりますが、第2引数 start を渡せばそこから数え始めます。画面に通し番号を出すときは start に 1 を指定すると、そのまま人間向けの番号になります。

2つの並びを同時に回したいときは zip です。zip は渡された反復可能なものから1つずつ取り出して組にします。3つ以上渡せば3要素以上のタプルになります。ここで大事なのは、長さが違うときの振る舞いです。zip は短い方に合わせて打ち切ります。余った要素は静かに捨てられ、エラーにも None での穴埋めにもなりません。長さが違うことに気づかないままデータを落としてしまう事故があるので、揃っているはずのデータなら長さを確かめてから渡す習慣を付けてください。

zip の結果を dict() に渡すと、キーの並びと値の並びから辞書ができます。dict(zip(keys, values)) はよく出てくる定型句です。ここでも短い方に合わせるので、キーの数と値の数が違えば、できる辞書の項目数は少ない方に合わせた数になります。

enumerate と zip が返すのはリストではありません。map や filter やジェネレータと同じ、イテレータと呼ばれる仕組みです。イテレータは前から順に1回だけ取り出せる使い切りの通路だと思ってください。一度取り出したものは戻ってきません。ですから同じ変数に対して list() を2回呼ぶと、1回目は中身が並んだリストになり、2回目は空のリストになります。何度も使いたいときは、最初に list() で受け止めて普通のリストにしておきます。この振る舞いは試験でもよく問われます。

新しいリストを作りたいだけなら、空のリストを用意して for で append する代わりに内包表記が書けます。[式 for 変数 in 反復可能なもの] という形で、後ろに if を付ければ条件に合うものだけを残せます。for を2つ並べれば二重ループになり、左に書いた for が外側のループです。読み方は「左端の式を、右側のループの分だけ作る」です。

波括弧を使えば辞書や集合も同じ形で作れます。{キー: 値 for ...} と書けば辞書内包表記、{値 for ...} と書けば集合内包表記です。集合内包表記では重複が自動的に消えるので、変換後の種類数を数えるような用途に向きます。

ここで引っかかりやすいのが丸括弧です。(式 for ...) と書いてもタプルはできません。これはジェネレータ式で、型は generator になります。Python にタプル内包表記という書き方は無く、タプルが欲しければ tuple(...) で包みます。ジェネレータ式は全要素を先に作らず、求められたときに1つずつ計算するので大きなデータでも省メモリですが、やはりイテレータなので使い切りです。

括弧の種類と、内包表記で作られるもの
書き方呼び名できるものの型
[x for x in it]リスト内包表記list
{x for x in it}集合内包表記set
{k: v for k, v in it}辞書内包表記dict
(x for x in it)ジェネレータ式generator
names = ["ume", "take", "matsu"]prices = [300, 500] for no, (n, p) in enumerate(zip(names, prices), 1):    print(no, n, p) # 1 ume 300# 2 take 500# 値段の側が2つしか無いので matsu は組にならず、静かに落ちる

用語

enumerate
反復可能なものから (番号, 要素) のタプルを順に返す組み込み関数。第2引数 start で数え始める値を指定でき、省略すると 0 から。
zip
複数の反復可能なものから1つずつ取って組にする組み込み関数。長さが違うときは最も短いものに合わせて打ち切る。
イテレータ
前から順に1つずつ値を取り出せる仕組み。取り出したものは戻らないので使い切りになる。enumerate・zip・map・filter・ジェネレータがこれにあたる。
リスト内包表記
[式 for 変数 in 反復可能なもの] という形で新しいリストを作る書き方。後ろに if を付けると絞り込みができる。
辞書内包表記
{キー: 値 for ...} という形で辞書を作る書き方。コロンがあるかどうかで集合内包表記と区別される。
集合内包表記
{値 for ...} という形で集合を作る書き方。重複した値は自動的に1つにまとまる。
ジェネレータ式
(式 for ...) という形。タプルではなく generator を作る。値を1つずつ計算するので省メモリだが、イテレータなので一度使うと尽きる。

例題

例題:例題: it に map の結果を入れ、print(len(list(it))) を書いた次の行で print(list(it)) を書いたら、2つ目が空のリストになった。なぜか。
答えと考え方 map が返すのはリストではなくイテレータで、前から1回だけ取り出せる使い切りの通路だからです。1つ目の list() で最後まで取り出してしまったので、2つ目の list() には何も残っていません。回数を数えたうえで中身も使いたいなら、先に data = list(it) と普通のリストで受け止めて、その data を2回使います。zip・filter・ジェネレータでも同じことが起きます。
例題:例題: tuple(c * 2 for c in "xy") は何になるか。丸括弧の中身は何か。
答えと考え方 丸括弧の中身はジェネレータ式であって、それ自体はタプルではありません。tuple() に渡して初めてタプルになるので、結果は ('xx', 'yy') です。Python にタプル内包表記という書き方は無いので、丸括弧で囲めばタプルができると思い込むのが典型的な誤りです。型を確かめたいときは type() に通すと generator と表示されます。

出典・根拠:Python Software Foundation「Python チュートリアル 5. データ構造」Python 3.14 ドキュメント(2026年8月確認)

3. リストとタプル 変わるものと変わらないもの

append と extend の違い、sort() が None を返す理由、スライスへの代入、1要素タプルのカンマ、そして浅いコピーの落とし穴が分かります。

リストとタプルはどちらも順番のある入れ物ですが、決定的な違いが1つあります。リストは後から中身を変えられるミュータブルな型で、タプルは変えられないイミュータブルな型です。タプルの要素に代入しようとすると TypeError になります。書き換えないと決めたデータをタプルにしておくと、うっかり壊す事故を型の側で防げます。

リストに要素を足す方法は2つあり、ここが最初の分かれ道です。append は引数をまるごと1つの要素として末尾に足します。extend は引数を反復して、取り出した値を1つずつ足します。リストを append すれば入れ子になって長さが1増え、同じリストを extend すれば中身がほどけて長さがその分増えます。文字列を extend すると1文字ずつばらばらに入るので、意図しない結果になりがちです。

次が最頻出の罠です。リストをその場で作り変えるメソッドは、作り変えた結果ではなく None を返します。sort() も reverse() も append() も extend() も insert() も、返るのは None です。ですから x = names.sort() と書くと x には None が入り、並べ替えたリストは names の側にあります。並べ替えた新しいリストが欲しいときは組み込み関数の sorted() を使います。sorted() は元のリストを一切変えず、新しいリストを返します。同じ関係が reverse() と reversed()、あるいはスライスによる逆順にもあります。

位置を指定して出し入れする道具も押さえておきます。insert(i, v) は i の位置に割り込ませ、それ以降の要素を後ろにずらします。pop() は末尾を取り除いてその値を返すので、破壊的でありながら値を返す数少ないメソッドです。pop(0) と書けば先頭を取り出せます。値が要らないなら del lst[i] で消せます。del は関数ではなく文なので、戻り値という考え方自体がありません。

スライスは範囲を指す書き方で、読むだけでなく代入や削除の対象にもできます。スライスに代入すると、その範囲がまるごと右辺の中身に置き換わります。左辺の幅と右辺の長さが違ってもよく、リストの長さがその分だけ変わります。範囲を2要素から1要素に置き換えれば全体は1つ縮み、幅0のスライスに代入すればその位置への挿入になります。del lst[1:3] と書けば範囲をまとめて削除できます。

タプルは丸括弧ではなくカンマで決まります。(1) は括弧で囲んだだけの整数で、型は int です。(1,) と末尾にカンマを置いて初めてタプルになります。空のタプルだけは () と書きます。もう1つ、タプルが不変であることの意味も正確に理解しておいてください。タプルが凍らせているのは「どの要素を指すか」であって、指した先の中身までは凍りません。タプルの中にリストが入っていれば、そのリストに append することはできます。

最後にコピーです。b = a は新しい入れ物を作らず、同じものに別の名前を付けるだけです。b = a[:] や copy.copy(a) は浅いコピーで、外側の入れ物は新しくなりますが、中の要素は元と同じものを共有します。ですから内側のリストを書き換えると、元の側にも見えてしまいます。内側まで切り離したいときは copy.deepcopy を使います。同じ理屈で、[[0] * 3] * 2 は同じリストを2回並べるだけなので、片方の行を変えるともう片方も変わります。行ごとに別のリストを作るなら [[0] * 3 for _ in range(2)] と書きます。

並べ替えや取り出しで、元のリストと戻り値がどうなるか
書き方元のリスト戻り値
lst.sort()並べ替わるNone
sorted(lst)変わらない並べ替えた新しいリスト
lst.reverse()逆順になるNone
lst[::-1]変わらない逆順の新しいリスト
lst.pop()末尾が消える取り出した要素
del lst[0]先頭が消える文なので戻り値は無い
import copy table = [["a"], ["b"]]shallow = table[:]deep = copy.deepcopy(table) shallow[0].append("X")deep[1].append("Y") print(table)     # [['a', 'X'], ['b']]  浅いコピー側の変更が元に見えているprint(shallow)   # [['a', 'X'], ['b']]print(deep)      # [['a'], ['b', 'Y']]  深いコピー側の変更は元に届かない

用語

ミュータブル
作った後で中身を変えられる性質。リスト・辞書・集合がこれにあたる。
イミュータブル
作った後で中身を変えられない性質。タプル・文字列・数値がこれにあたる。ただしタプルの中のリストは変更できる。
append
引数をまるごと1つの要素として末尾に足すリストのメソッド。戻り値は None。
extend
引数を反復して取り出した値を1つずつ末尾に足すリストのメソッド。戻り値は None。
sorted
並べ替えた新しいリストを返す組み込み関数。元のリストは変わらない。その場で並べ替えるメソッドの sort() とは別物。
スライス代入
lst[i:j] = [...] という形で範囲をまるごと置き換える書き方。左辺の幅と右辺の長さが違ってもよく、リストの長さが変わる。
浅いコピー
外側の入れ物だけを新しく作り、中の要素は元と共有するコピー。lst[:] や copy.copy() がこれにあたる。
深いコピー
入れ子の中身まで再帰的に複製するコピー。copy.deepcopy() で行う。元とまったく共有しない。

例題

例題:例題: ranking = names.sort() と書いたら ranking が None になった。何を直せばよいか。
答えと考え方 sort() はリストをその場で並べ替えたうえで None を返すメソッドだからです。並べ替えた結果は names の側に入っています。names.sort() だけを実行してから names を使うか、元のリストを残したいなら ranking = sorted(names) と書きます。reverse() や append() も同じく None を返すので、メソッドの戻り値を変数で受ける書き方を見たら疑ってください。
例題:例題: 3人分の空の持ち物リストを作ろうと bags = [[]] * 3 と書き、bags[0] に1つ足したら3人とも同じものを持ってしまった。どう書くか。
答えと考え方 [[]] * 3 は空のリストを3つ作るのではなく、同じ1つの空リストへの参照を3つ並べただけだからです。どれを変えても同じ実体を変えていることになります。bags = [[] for _ in range(3)] と内包表記で書けば、繰り返しのたびに新しいリストが作られるので3つが独立します。掛け算でリストを増やしたときは、中身がミュータブルかどうかを必ず確かめてください。

出典・根拠:Python Software Foundation「Python チュートリアル 5. データ構造」Python 3.14 ドキュメント(2026年8月確認)

4. 辞書と集合 キーで引く入れ物

添字ではなくキーで引く辞書と、重複を持たない集合。get と setdefault の違い、in が何を見ているか、そして空の波括弧が何になるかが分かります。

辞書はキーと値の組を並べた入れ物です。リストが0から始まる番号で引くのに対し、辞書は自分で決めたキーで引きます。d[key] で取り出し、d[key] = value で追加または上書きします。既にあるキーに代入すれば上書きになり、無いキーに代入すれば新しい項目が増えます。取り出すときだけは事情が違い、無いキーを d[key] で引くと KeyError になります。

この KeyError を避ける道具が2つあります。get は、キーがあればその値を返し、無ければ None を返します。第2引数を渡せば、無いときにその値を返します。もう1つの setdefault は、キーがあれば既存の値を返して辞書を変えず、無ければ第2引数を入れてからその値を返します。読むだけなら get、無ければ作りたいなら setdefault、と覚えると迷いません。集計で d[k] = d.get(k, 0) + 1 と書き、グループ分けで d.setdefault(k, []).append(v) と書くのが定型です。

辞書を見て回るときは items keys values を使います。items は (キー, 値) のタプルを返すので、for k, v in d.items() と2つの変数で受けます。keys はキーだけ、values は値だけです。辞書をそのまま for に渡すとキーが順に取り出されるので、keys は省略されることもあります。なお Python 3.7 以降、辞書は挿入した順序を保ちます。

in 演算子は辞書に対してキーだけを見ます。値がいくら一致していても、キーに無ければ False です。1 in {'a': 1} が False になるのはそのためで、値を調べたいなら 1 in d.values() と明示します。ここは試験でも実務でも取り違えやすいところです。

辞書の作り方はいくつかあります。波括弧のリテラルで直接書く方法のほか、dict(a=1, b=2) のようにキーワード引数から作る方法、dict([('a', 1), ('b', 2)]) のように組の並びから作る方法があります。キーワード引数の形は書きやすい反面、キーが識別子として書ける文字列に限られます。またリテラルの中で同じキーを2度書いた場合はエラーにならず、後に書いた方が残ります。

集合は重複を持たない入れ物です。リストを set() に通すと重複が消えるので、種類の数を数えるときに便利です。集合どうしは演算子でまとめて扱えます。縦棒は和集合でどちらかにあるもの、アンパサンドは積集合で両方にあるもの、マイナスは差集合で左にだけあるもの、ハットは対称差でどちらか一方にだけあるものです。部分集合かどうかは不等号で調べられます。

最後に2つの落とし穴です。1つは、空の波括弧 {} は空の辞書だということ。要素が無いと辞書とも集合とも決められないので、Python は辞書として扱います。空の集合が欲しいときは set() と書きます。もう1つは、集合の要素と辞書のキーはハッシュ可能でなければならないということ。数値・文字列・タプルは入れられますが、リストや辞書を入れようとすると unhashable type という TypeError になります。中身が変わりうるものは、キーとしての置き場所が定まらないからです。集合と辞書の表示順に意味を求めないことも合わせて覚えておいてください。

キーを引く4つの書き方の違い
書き方キーが有るときキーが無いとき辞書は変わるか
d[k]値を返すKeyError になる変わらない
d.get(k)値を返すNone を返す変わらない
d.get(k, v)値を返すv を返す変わらない
d.setdefault(k, v)値を返すv を返す無いときだけ増える
stock = {}for item in ["pen", "note", "pen", "clip", "pen"]:    stock[item] = stock.get(item, 0) + 1print(stock)   # {'pen': 3, 'note': 1, 'clip': 1} group = {}for k, v in [("fruit", "ume"), ("veg", "nasu"), ("fruit", "kaki")]:    group.setdefault(k, []).append(v)print(group)   # {'fruit': ['ume', 'kaki'], 'veg': ['nasu']}

用語

辞書
キーと値の組を持つ入れ物。キーで値を引く。無いキーを角括弧で引くと KeyError になる。
get
キーがあれば値を、無ければ None または第2引数の値を返す辞書のメソッド。辞書自体は変わらない。
setdefault
キーがあれば既存の値を返し、無ければ第2引数を入れてから返す辞書のメソッド。無いときだけ辞書が増える。
items
辞書から (キー, 値) の組を順に取り出すメソッド。for k, v in d.items() の形で使う。
集合
重複を持たない入れ物。リストを set() に通すと重複が消える。要素はハッシュ可能でなければならない。
対称差
2つの集合のどちらか一方にだけある要素を集めたもの。ハット記号で書き、両方にある要素は落ちる。
ハッシュ可能
内容から一定の値を計算でき、その値が変わらない性質。数値・文字列・タプルは該当し、リストや辞書は該当しない。

例題

例題:例題: 商品名ごとの個数を数えようと count[name] += 1 と書いたら、最初の商品で KeyError になった。どう直すか。
答えと考え方 += は右辺で count[name] を読んでから足すので、まだ登録されていないキーでは読む時点で KeyError になります。count[name] = count.get(name, 0) + 1 と書けば、無いときは 0 から数え始められます。先に count.setdefault(name, 0) を呼んでおく方法もあります。標準ライブラリの collections.defaultdict(int) を使えば、未知のキーが自動的に 0 で始まります。
例題:例題: 2つの名簿 A と B から、片方にしか載っていない人だけを取り出したい。どの演算を使うか。
答えと考え方 対称差を使います。A ^ B と書けば、A だけにいる人と B だけにいる人が集まり、両方に載っている人は落ちます。ついでに整理しておくと、両方にいる人は A & B、A にだけいる人は A - B、全員をまとめたいなら A | B です。名簿がリストなら set() に通してから演算し、結果を並べて見せたいときは sorted() で順序を決めます。

出典・根拠:Python Software Foundation「Python チュートリアル 5. データ構造」Python 3.14 ドキュメント(2026年8月確認)

確認問題(40問)

四肢択一。「正解と解説」を開くと、正解の理由と他の選択肢が違う理由を確認できます。

問1|for/else

for 文に else 節を付けた次のコードを実行したとき、出力される内容はどれか。

for n in range(4):    if n == 9:        breakelse:    print("done")print(n)
  1. 3 だけが出力され done は出ない
  2. done だけが出力され 3 は出ない
  3. done と 3 がこの順に出力される
  4. 3 と done がこの順に出力される
正解と解説
正解:C. done と 3 がこの順に出力される

for に付けた else 節は、ループが break されずに終わったときに実行される。range(4) の中に 9 は無いので break は一度も起きず、ループを最後まで回ってから else の print が動いて done が出る。その後の print(n) は、ループを抜けた時点で n に残っている最後の値 3 を出す。出力の順序を取り違えると 3 が先に来る形になり、else はループの終了時に必ず飛ばされるものと誤解すると done の出ない形になる。n がループを抜けた後も残ることを見落とすと 3 の出ない形になる。

根拠:Python Software Foundation「Python チュートリアル 4. その他の制御フローツール」Python 3.14 ドキュメント(2026年8月確認)

問2|breakとelse

break でループを抜けた場合に else 節がどう扱われるかを確かめる。次のコードの出力はどれか。

for c in "abc":    if c == "b":        break    print(c)else:    print("no break")
  1. a が出力され no break は出力されない
  2. a と no break がこの順に出力される
  3. a と b の2つがこの順に出力される
  4. a b c と no break がすべて出力される
正解と解説
正解:A. a が出力され no break は出力されない

1周目は c が a なので print(c) が動いて a が出る。2周目に c が b になり break でループを打ち切る。for の else 節は break されずに終わったときだけ実行される決まりなので、ここではスキップされ no break は出ない。else をループ終了時に必ず動くものと思い込むと no break まで出る形になり、break の前に print(c) があると読み違えると b まで出る形になる。break 自体を見落とすと a b c がすべて出る形になる。

根拠:Python Software Foundation「Python チュートリアル 4. その他の制御フローツール」Python 3.14 ドキュメント(2026年8月確認)

問3|空でもelse

反復の対象が空だったとき、for の else 節がどうなるかを問う。次のコードの実行結果はどれか。

items = []for it in items:    print(it)else:    print("finished")
  1. 何も出力されないままループを抜けて終わる
  2. else 節が無視され TypeError になる
  3. 反復が0回なので StopIteration になる
  4. finished が1回だけ出力される
正解と解説
正解:D. finished が1回だけ出力される

for の else 節が実行される条件は「break されずにループが終わったこと」であって、「1回以上反復したこと」ではない。items が空なので本体は1回も動かないが、break もしていないため else はそのまま実行され finished が出る。空なら else も飛ばされると考えると何も出力されない形になる。空のリストを for に渡すこと自体は正しい書き方なので例外にはならず、TypeError や StopIteration が送出されることもない。

根拠:Python Software Foundation「Python チュートリアル 4. その他の制御フローツール」Python 3.14 ドキュメント(2026年8月確認)

問4|while/else

while 文に else 節を付け、途中で break した場合を考える。次のコードの出力はどれか。

n = 5while n > 0:    n -= 1    if n == 2:        breakelse:    print("loop ended")print(n)
  1. loop ended と 0 がこの順に出力される
  2. 2 が出力され loop ended は出力されない
  3. loop ended と 2 がこの順に出力される
  4. 0 が出力され loop ended は出力されない
正解と解説
正解:B. 2 が出力され loop ended は出力されない

n は 5 から 1 ずつ減り、4・3 と進んで 2 になった時点で break する。while の else 節も for と同じく break されずに終わったときだけ実行されるので、ここではスキップされ loop ended は出ない。残るのは print(n) の 2 だけである。else が必ず動くと考えると loop ended まで出る形になり、break を見落として条件が偽になるまで回ると誤読すると n が 0 になる形になる。

根拠:Python Software Foundation「Python チュートリアル 4. その他の制御フローツール」Python 3.14 ドキュメント(2026年8月確認)

問5|continue

continue と break を1つのループに混ぜた次のコードを実行したとき、最後に出力されるリストはどれか。

out = []for i in range(6):    if i == 3:        continue    if i == 5:        break    out.append(i)print(out)
  1. [0, 1, 2, 4]
  2. [0, 1, 2, 4, 5]
  3. [0, 1, 2, 3, 4]
  4. [0, 1, 2, 3]
正解と解説
正解:A. [0, 1, 2, 4]

i が 0・1・2 のときは2つの if をどちらも通り抜けて append される。i が 3 のとき continue が働き、その回の残り、つまり append が飛ばされる。i が 4 のときは再び append され、i が 5 のとき break でループを打ち切るので append は行われない。したがって [0, 1, 2, 4] になる。break の回も追加されると考えると 5 まで並ぶ形になり、continue を pass のように扱うと 3 が残る形になる。

根拠:Python Software Foundation「Python チュートリアル 4. その他の制御フローツール」Python 3.14 ドキュメント(2026年8月確認)

問6|rangeの逆順

range に負の刻み幅を渡した場合の並びを問う。次のコードの出力はどれか。

print(list(range(10, 0, -3)))
  1. [9, 6, 3, 0]
  2. [7, 4, 1, -2]
  3. [10, 7, 4, 1]
  4. [10, 7, 4, 1, 0]
正解と解説
正解:C. [10, 7, 4, 1]

range(start, stop, step) は start から始めて step ずつ進み、stop に達する手前で止まる。ここでは 10 から 3 ずつ引いて 10・7・4・1 と進み、次の -2 は 0 以下なので採用されない。stop の 0 は含まれないので、末尾に 0 が並ぶ形にはならない。start を含まないと誤解すると 7 から始まる形になり、start を1つ手前から数え始めると考えると 9 から始まる形になる。stop を含まないという点は正の刻み幅のときと同じである。

根拠:Python Software Foundation「Python 標準ライブラリ 組み込み関数」Python 3.14 ドキュメント(2026年8月確認)

問7|rangeの型

組み込み関数 range を呼んで得られるオブジェクトの説明として適切なものはどれか。

  1. generator 型のオブジェクトで、一度反復すると空になる
  2. range 型のオブジェクトで、list() に渡すとリストになる
  3. list 型のオブジェクトで、そのまま角括弧付きで表示される
  4. tuple 型のオブジェクトで、要素の差し替えができない
正解と解説
正解:B. range 型のオブジェクトで、list() に渡すとリストになる

range が返すのは range 型のオブジェクトで、必要な整数をその都度計算して返す。リストのように全要素を先に持たないので、大きな範囲でもメモリを食わない。中身を並べて確かめたいときは list() に通す。type(range(3)) は range であって list でも tuple でもなく、そのまま表示しても要素の並びではなく range(0, 3) と出る。また使い切りではなく何度でも反復できるので generator でもない。なお添字で読めて要素の差し替えができない点はタプルと同じなので、その性質だけでは tuple と区別できない。

根拠:Python Software Foundation「Python 標準ライブラリ 組み込み関数」Python 3.14 ドキュメント(2026年8月確認)

問8|短絡評価

論理演算子 or と and が何を返すかを確かめる。次のコードの出力はどれか。

print([] or 0 or "z")print(1 and 0 and 2)
  1. True と False がこの順に出力される
  2. z と 2 がこの順に出力される
  3. False と 0 がこの順に出力される
  4. z と 0 がこの順に出力される
正解と解説
正解:D. z と 0 がこの順に出力される

or は左から評価して最初に真になった値をそのまま返す。空のリストも 0 も偽なので、最後の "z" が返る。and は逆に最初に偽になった値を返すので、1 は真、次の 0 で偽が確定して 0 が返り、右端の 2 は評価されない。返るのは真偽値ではなく評価をやめた時点の値なので、True や False が出ることはない。and が右端の 2 を返すのは、途中がすべて真だった場合だけである。

根拠:Python Software Foundation「Python チュートリアル 4. その他の制御フローツール」Python 3.14 ドキュメント(2026年8月確認)

問9|連鎖比較

比較の連鎖と三項演算子を組み合わせた次のコードを実行したとき、出力される内容はどれか。

x = 3print(1 < x < 5)print("yes" if x % 2 else "no")
  1. False と yes がこの順に出力される
  2. False と no がこの順に出力される
  3. True と yes がこの順に出力される
  4. True と no がこの順に出力される
正解と解説
正解:C. True と yes がこの順に出力される

1 < x < 5 は (1 < x) and (x < 5) と同じ意味で、x が 3 ならどちらも成り立つので True になる。三項演算子は 真のときの値 if 条件 else 偽のときの値 という並びで、条件は x % 2 すなわち 1 である。Python では 0 以外の整数は真として扱われるので yes が選ばれる。連鎖比較を 1 < (x < 5) のように後ろから結合すると読み違えると、x < 5 が True すなわち 1 になり 1 < 1 で False という誤答になる。また 1 を偽と考えると no が選ばれる形になる。

根拠:Python Software Foundation「Python チュートリアル 4. その他の制御フローツール」Python 3.14 ドキュメント(2026年8月確認)

問10|passの役割

Python の pass 文の説明として適切なものはどれか。

  1. 構文上ブロックが必要な場所で、何もしないことを示す
  2. ループの残りをとばして次の反復に進むことを示す
  3. ループそのものを打ち切って外へ抜けることを示す
  4. 関数の実行を終えて呼び出し元に値を返すことを示す
正解と解説
正解:A. 構文上ブロックが必要な場所で、何もしないことを示す

Python はインデントでブロックを表すため、空のブロックを書くことができない。クラスや関数の中身を後で書くつもりのときや、条件に当てはまったときにあえて何もしないときに、その場所を埋めるのが pass である。処理の流れを変える働きは無い。次の反復に進むのは continue、ループを打ち切るのは break、呼び出し元に値を返すのは return であり、いずれも pass とは役割が異なる。

根拠:Python Software Foundation「Python チュートリアル 4. その他の制御フローツール」Python 3.14 ドキュメント(2026年8月確認)

問11|enumerate

enumerate に第2引数を渡した次のコードを実行したとき、画面に出るのはどれか。

for i, name in enumerate(["gu", "choki", "pa"], 1):    print(i, name)
  1. 1 gu / 2 choki の2行だけが出力される
  2. 1 gu / 2 choki / 3 pa の3行が出力される
  3. 0 gu / 1 choki / 2 pa の3行が出力される
  4. gu 1 / choki 2 / pa 3 の3行が出力される
正解と解説
正解:B. 1 gu / 2 choki / 3 pa の3行が出力される

enumerate は (番号, 要素) のタプルを順に返し、第2引数 start で数え始める値を指定できる。ここでは 1 を渡しているので番号は 1・2・3 となる。start を省略したときの 0 始まりと混同すると 0 から始まる形になる。返るタプルは番号が先で要素が後なので、print(i, name) の並びもその順になり、名前が先に出ることはない。要素は3つとも取り出されるので、2行で打ち切られることもない。

根拠:Python Software Foundation「Python 標準ライブラリ 組み込み関数」Python 3.14 ドキュメント(2026年8月確認)

問12|zipの長さ

長さの違う2つのリストを zip に渡した。次のコードの実行結果はどれか。

print(list(zip([1, 2, 3], [10, 20])))
  1. [(10, 1), (20, 2)]
  2. [(1, 10), (2, 20), (3, 0)]
  3. [(1, 10), (2, 20), (3,)]
  4. [(1, 10), (2, 20)]
正解と解説
正解:D. [(1, 10), (2, 20)]

zip は渡された反復可能なものから1つずつ取り出して組にし、いちばん短いものが尽きた時点で終わる。ここでは2つ目のリストが2要素なので、組は2つしか作られず、余った 3 は静かに捨てられる。エラーにはならず、余りが 0 で埋められることも、片方だけのタプルが作られることもない。組の中身は渡した順に並ぶので、10 と 1 のように入れ替わることもない。

根拠:Python Software Foundation「Python 標準ライブラリ 組み込み関数」Python 3.14 ドキュメント(2026年8月確認)

問13|zipで分解

組にしたデータを、星印つきで zip に渡し直した。次のコードの出力はどれか。

pairs = [(1, 'a'), (2, 'b'), (3, 'c')]nums, chars = zip(*pairs)print(nums)print(chars)
  1. (1, 2, 3) のあとに ('a', 'b', 'c') が出力される
  2. [1, 2, 3] のあとに ['a', 'b', 'c'] が出力される
  3. (1, 'a') のあとに (2, 'b') が出力される
  4. ((1, 'a'),) のあとに ((2, 'b'),) が出力される
正解と解説
正解:A. (1, 2, 3) のあとに ('a', 'b', 'c') が出力される

星印を付けると、リストの中の組が1つずつ別々の引数として zip に渡される。つまり zip((1, 'a'), (2, 'b'), (3, 'c')) を呼んだのと同じことになり、各組の1番目どうし、2番目どうしが集められて (1, 2, 3) と ('a', 'b', 'c') の2本に分かれる。組にしたものを元の2本に戻す定石で、zip を2回通すと元に戻る。返るのはリストではなくタプルなので角括弧の形にはならない。星印を付け忘れて zip(pairs) と書くと、組そのものが1つの引数として渡され、((1, 'a'),) のように1要素のタプルが並ぶ形になる。

根拠:Python Software Foundation「Python チュートリアル 5. データ構造」Python 3.14 ドキュメント(2026年8月確認)

問14|dictとzip

キーの並びと値の並びから辞書を組み立てる。次のコードの実行結果はどれか。

keys = ["a", "b", "c"]vals = [10, 20, 30]print(dict(zip(keys, vals)))
  1. [('a', 10), ('b', 20), ('c', 30)]
  2. {'a', 'b', 'c', 10, 20, 30}
  3. {'a': 10, 'b': 20, 'c': 30}
  4. {10: 'a', 20: 'b', 30: 'c'}
正解と解説
正解:C. {'a': 10, 'b': 20, 'c': 30}

zip(keys, vals) は (キー, 値) というタプルを順に返し、dict() はその組の並びを受け取って辞書を作る。組の1つ目がキー、2つ目が値になるので、数値がキーになる形にはならない。dict() に通しているので、タプルのリストのままにもならない。波括弧で表示されても、コロンで組になっているのが辞書、値が並ぶだけなのが集合である。

根拠:Python Software Foundation「Python チュートリアル 5. データ構造」Python 3.14 ドキュメント(2026年8月確認)

問15|リスト内包

リスト内包表記を使った次のコードを実行したとき、出力されるリストはどれか。

print([n * n for n in range(1, 5)])
  1. [0, 1, 4, 9]
  2. [1, 4, 9, 16, 25]
  3. [2, 4, 6, 8]
  4. [1, 4, 9, 16]
正解と解説
正解:D. [1, 4, 9, 16]

range(1, 5) が返すのは 1・2・3・4 で、stop に指定した 5 は含まれない。それぞれを2乗すると 1・4・9・16 になる。range を 0 始まりだと思い込むと 0 から並ぶ形になり、stop を含むと誤解すると 25 まで並ぶ形になる。n * n を n * 2 と読み違えると 2 ずつ増える形になる。内包表記は左端の式を各要素について評価し、その結果を並べた新しいリストを作るという読み方を身につけておきたい。

根拠:Python Software Foundation「Python チュートリアル 5. データ構造」Python 3.14 ドキュメント(2026年8月確認)

問16|辞書内包

波括弧の中にコロンを書いた内包表記を実行する。次のコードの出力はどれか。

words = ["sun", "moon"]print({w: len(w) for w in words})
  1. {'sun', 'moon', 3, 4}
  2. {'sun': 3, 'moon': 4}
  3. {3: 'sun', 4: 'moon'}
  4. [('sun', 3), ('moon', 4)]
正解と解説
正解:B. {'sun': 3, 'moon': 4}

波括弧の中にコロンがある内包表記は辞書内包表記で、コロンの左がキー、右が値になる。ここでは単語をキー、その文字数を値とする辞書ができる。キーと値を逆に読むと文字数がキーになる形になる。角括弧で囲めばタプルのリストになるが、ここは波括弧なのでそうはならない。コロンが無ければ集合内包表記になり値が並ぶだけの表示になるが、コロンがある以上できるのは辞書である。

根拠:Python Software Foundation「Python チュートリアル 5. データ構造」Python 3.14 ドキュメント(2026年8月確認)

問17|丸括弧の型

内包表記のような式を丸括弧で囲んだ。次のコードを実行したとき表示される型はどれか。

g = (n for n in range(3))print(type(g))
  1. <class 'list'>
  2. <class 'range'>
  3. <class 'generator'>
  4. <class 'tuple'>
正解と解説
正解:C. <class 'generator'>

Python にタプル内包表記という書き方は無く、丸括弧で囲んだこの形はジェネレータ式になる。型は generator で、値を先にすべて作らず求められたときに1つずつ計算するので省メモリだが、イテレータなので一度使うと尽きる。タプルが欲しいときは tuple() で包む。角括弧で書けばリスト内包表記になって list に、range(3) をそのまま代入すれば range になる。tuple はこの書き方では得られない。

根拠:Python Software Foundation「Python チュートリアル 5. データ構造」Python 3.14 ドキュメント(2026年8月確認)

問18|集合内包

集合内包表記で作った入れ物の要素数を数える。次のコードの出力はどれか。

print(len({n % 4 for n in range(10)}))
  1. 4 が出力される
  2. 10 が出力される
  3. 3 が出力される
  4. 0 が出力される
正解と解説
正解:A. 4 が出力される

range(10) の各値を 4 で割った余りは 0・1・2・3・0・1・2・3・0・1 となる。波括弧でコロンが無い内包表記は集合内包表記なので、重複した値は1つにまとめられ、残るのは 0・1・2・3 の4種類である。重複が消えることを見落として値の個数をそのまま数えると 10 になる。余りに 0 が含まれることを見落として 1・2・3 の3種類と数えると 3 になる。0 は内包表記が何も作らないと誤解した場合の値だが、range(10) を回るかぎり中身が空になることはない。集合の表示順は決まっていないため、要素数で確かめるのが確実である。

根拠:Python Software Foundation「Python チュートリアル 5. データ構造」Python 3.14 ドキュメント(2026年8月確認)

問19|二重の内包

for を2つ並べた内包表記の並び順を問う。次のコードの実行結果はどれか。

print([(x, y) for x in [1, 2] for y in "ab"])
  1. [(1, 'a'), (2, 'a'), (1, 'b'), (2, 'b')]
  2. [('a', 1), ('b', 1), ('a', 2), ('b', 2)]
  3. [(1, 'a'), (2, 'b'), (1, 'b'), (2, 'a')]
  4. [(1, 'a'), (1, 'b'), (2, 'a'), (2, 'b')]
正解と解説
正解:D. [(1, 'a'), (1, 'b'), (2, 'a'), (2, 'b')]

内包表記に for を2つ並べたときは、左に書いた for が外側のループになる。通常の for 文を入れ子にして書いた場合とまったく同じ順序で、x を 1 に固定して y を a・b と回し、次に x を 2 にして同じことを繰り返す。右の for を外側だと読むと x が先に回る順序になる。組の中身は式に書いた (x, y) の並びどおりなので、文字が先に来ることはない。

根拠:Python Software Foundation「Python チュートリアル 5. データ構造」Python 3.14 ドキュメント(2026年8月確認)

問20|start引数

組み込み関数 enumerate の第2引数 start の説明として適切なものはどれか。

  1. どの要素から取り出すかを指定する。省略すると先頭から取る
  2. 数え始める番号を指定する。省略すると 0 から数える
  3. 何個目まで数えるかを指定する。省略すると最後まで数える
  4. 何個ずつ飛ばすかを指定する。省略すると1つずつ進む
正解と解説
正解:B. 数え始める番号を指定する。省略すると 0 から数える

enumerate の第2引数 start は、付ける番号をいくつから始めるかだけを決める。既定は 0 なので、1 を渡せば人間向けの通し番号になる。番号の付け方が変わるだけで、取り出される要素の範囲や個数は変わらない点が肝心である。個数を制限したり飛ばしたりする働きは無く、取り出しの開始位置をずらすものでもない。これらはいずれもスライスなど別の道具の説明である。

根拠:Python Software Foundation「Python 標準ライブラリ 組み込み関数」Python 3.14 ドキュメント(2026年8月確認)

問21|sortの戻り値

リストの sort メソッドの戻り値を変数で受けた。次のコードの出力はどれか。

nums = [5, 3, 9]result = nums.sort()print(result)print(nums)
  1. [3, 5, 9] と [3, 5, 9] がこの順に出力される
  2. [3, 5, 9] と [5, 3, 9] がこの順に出力される
  3. None と [5, 3, 9] がこの順に出力される
  4. None と [3, 5, 9] がこの順に出力される
正解と解説
正解:D. None と [3, 5, 9] がこの順に出力される

sort はリストをその場で並べ替えるメソッドで、戻り値は None である。したがって result には None が入り、並べ替えた結果は nums の側に残る。並べ替えた新しいリストが返ると思い込むと result 側にリストが入る形になる。sort が元のリストを変えることを見落とすと nums が元の並びのままになる形になる。元を残したまま並べ替えたリストが欲しいときは、組み込み関数の sorted を使う。

根拠:Python Software Foundation「Python チュートリアル 5. データ構造」Python 3.14 ドキュメント(2026年8月確認)

問22|sortedの違い

リストの sort メソッドと組み込み関数 sorted の違いとして適切なものはどれか。

  1. どちらもその場で並べ替えたうえで、並べ替えたリストを返す
  2. どちらも新しいリストを返し、元のリストはどちらも変わらない
  3. sort はその場で並べ替えて None を返し、sorted は新しいリストを返す
  4. sort は新しいリストを返し、sorted はその場で並べ替えて None を返す
正解と解説
正解:C. sort はその場で並べ替えて None を返し、sorted は新しいリストを返す

sort はリストのメソッドで、そのリスト自身を並べ替え、戻り値としては None を返す。sorted は組み込み関数で、元の並びをまったく変えずに並べ替えた新しいリストを返す。元を残したいかどうかで選び分ける。両者の役割を入れ替えて覚えると、sort が新しいリストを返すという説明になる。破壊的かどうかを一方に寄せて考えると、両方がその場で並べ替えるとか、両方が元を変えないといった説明になる。なお sorted はリスト以外の反復可能なものも受け取れ、結果は常にリストになる。

根拠:Python Software Foundation「Python チュートリアル 5. データ構造」Python 3.14 ドキュメント(2026年8月確認)

問23|appendの差

リストに別のリストを足す2つの方法を比べる。次のコードの出力はどれか。

a = [1, 2]a.append([3, 4])b = [1, 2]b.extend([3, 4])print(a, b)
  1. [1, 2, [3, 4]] [1, 2, 3, 4]
  2. [1, 2, 3, 4] [1, 2, [3, 4]]
  3. [1, 2, [3, 4]] [1, 2, [3, 4]]
  4. [1, 2, 3, 4] [1, 2, 3, 4]
正解と解説
正解:A. [1, 2, [3, 4]] [1, 2, 3, 4]

append は引数をまるごと1つの要素として末尾に足すので、リストを渡せば入れ子になり長さは1だけ増える。extend は引数を反復して取り出した値を1つずつ足すので、中身がほどけて長さが2増える。2つの役割を入れ替えると a と b の結果が逆になる。どちらも同じ働きだと考えると、両方が入れ子になる形か、両方が平らになる形になる。どちらのメソッドも戻り値は None なので、結果を変数で受けてはいけない点も合わせて覚えておきたい。

根拠:Python Software Foundation「Python チュートリアル 5. データ構造」Python 3.14 ドキュメント(2026年8月確認)

問24|浅いコピー

入れ子のリストをスライスで複製し、内側を書き換えた。次のコードの実行結果はどれか。

orig = [[1, 2], [3, 4]]copy1 = orig[:]copy1[0].append(9)print(orig)
  1. [[1, 2], [3, 4], 9]
  2. [[1, 2, 9], [3, 4]]
  3. [[1, 2], [3, 4]]
  4. [[1, 2, 9], [3, 4, 9]]
正解と解説
正解:B. [[1, 2, 9], [3, 4]]

スライスによる複製は浅いコピーで、外側のリストは新しく作られるが、中に入っている要素は元と同じものを共有する。copy1[0] と orig[0] は同じリストを指しているので、そこに append すると元の側にも見える。完全に切り離せると思い込むと元が変わらない形になる。書き換えたのは先頭の内側リストだけなので後ろの要素まで伸びることはなく、外側に足したわけでもないので 9 が外側に並ぶこともない。内側まで切り離すには copy.deepcopy を使う。

根拠:Python Software Foundation「Python 標準ライブラリ copy --- 浅いコピーおよび深いコピー操作」Python 3.14 ドキュメント(2026年8月確認)

問25|深いコピー

深いコピーと浅いコピーを1つのコードで比べる。実行後に base はどうなるか。

import copybase = [[1, 2], [3, 4]]d = copy.deepcopy(base)s = base[:]d[0].append(8)s[1].append(7)print(base)
  1. [[1, 2], [3, 4]]
  2. [[1, 2, 8], [3, 4]]
  3. [[1, 2], [3, 4, 7]]
  4. [[1, 2, 8], [3, 4, 7]]
正解と解説
正解:C. [[1, 2], [3, 4, 7]]

copy.deepcopy は入れ子の中身まで複製するので、d[0] は base[0] とは別のリストになり、そこへの append は base に届かない。一方 s は浅いコピーなので s[1] と base[1] は同じリストであり、そこへの append は base にも見える。したがって後ろの要素だけが伸びる。両方が届くと考えると内側の2つとも伸びる形になり、どちらも届かないと考えると元のままの形になる。深いコピーと浅いコピーを取り違えると、前の要素だけが伸びる形になる。

根拠:Python Software Foundation「Python 標準ライブラリ copy --- 浅いコピーおよび深いコピー操作」Python 3.14 ドキュメント(2026年8月確認)

問26|かけ算の罠

リストの掛け算で二次元の表を作ろうとした。次のコードの実行結果はどれか。

grid = [[0] * 3] * 2grid[0][1] = 5print(grid)
  1. [[0, 5, 0], [0, 0, 0]]
  2. [[0, 0, 0], [0, 5, 0]]
  3. [[5, 0, 0], [5, 0, 0]]
  4. [[0, 5, 0], [0, 5, 0]]
正解と解説
正解:D. [[0, 5, 0], [0, 5, 0]]

外側の掛け算は新しい行を作るのではなく、同じ1つのリストへの参照を2つ並べるだけである。grid[0] と grid[1] は同じ実体なので、片方の添字1の位置を書き換えると、もう片方でも同じ位置が変わって見える。行が独立していると考えると片方の行だけが変わる形になる。書き換えたのは添字1の位置なので、先頭が 5 になる形にもならない。行ごとに独立させるには [[0] * 3 for _ in range(2)] と書く。

根拠:Python Software Foundation「Python チュートリアル 5. データ構造」Python 3.14 ドキュメント(2026年8月確認)

問27|1要素タプル

丸括弧で囲んだだけの値と、末尾にカンマを置いた値の型を比べる。次のコードの出力はどれか。

x = (7)y = (7,)print(type(x).__name__, type(y).__name__)
  1. int と tuple がこの順に出力される
  2. tuple と tuple がこの順に出力される
  3. tuple と int がこの順に出力される
  4. int と int がこの順に出力される
正解と解説
正解:A. int と tuple がこの順に出力される

タプルを決めるのは丸括弧ではなくカンマである。(7) は計算の優先順位を示す括弧で囲んだだけの整数なので型は int になり、(7,) と末尾にカンマを置いて初めて要素1個のタプルになる。括弧で囲めばタプルになると思い込むと両方が tuple になる形になり、2つを取り違えると順序が逆の形や両方 int の形になる。なお空のタプルだけは例外で、カンマの無い () と書く。

根拠:Python Software Foundation「Python チュートリアル 5. データ構造」Python 3.14 ドキュメント(2026年8月確認)

問28|タプルの中身

タプルの中に入れたリストへ要素を足そうとした。次のコードの実行結果はどれか。

t = (1, [2, 3], 4)t[1].append(5)print(t)
  1. (1, [2, 3], 4, 5)
  2. (1, [2, 3], 4)
  3. (1, [2, 3, 5], 4)
  4. TypeError が送出される
正解と解説
正解:C. (1, [2, 3, 5], 4)

タプルが凍らせているのは、どの要素を指すかという対応であって、指した先の中身までは凍らない。t[1] はリストであり、そのリスト自体はミュータブルなので append できる。タプルの要素そのものに代入する t[1] = [] のような書き方なら TypeError になるが、ここでは要素を差し替えていない。足したのはリストの中なので、タプルの長さが増えることも、まったく変わらないままで済むこともない。

根拠:Python Software Foundation「Python チュートリアル 5. データ構造」Python 3.14 ドキュメント(2026年8月確認)

問29|スライス代入

リストのスライスに、長さの違うリストを代入した。次のコードの出力はどれか。

x = [1, 2, 3, 4, 5]x[1:3] = [9]print(x)
  1. [1, 2, 9, 4, 5]
  2. [1, 9, 4, 5]
  3. [1, 9, 3, 4, 5]
  4. [1, 9, 9, 4, 5]
正解と解説
正解:B. [1, 9, 4, 5]

スライスへの代入は、指定した範囲をまるごと右辺の中身に置き換える操作である。x[1:3] は 2 と 3 の2要素を指すので、それが 9 の1要素に置き換わり、全体の長さは5から4に減る。1要素だけが差し替わると考えると長さが5のままの形になり、右辺が幅に合わせて引き伸ばされると考えると 9 が2つ並ぶ形になる。範囲の始まりを1つずらして読むと 2 が残る形になる。左辺の幅と右辺の長さが違ってよいのがスライス代入の特徴である。

根拠:Python Software Foundation「Python チュートリアル 5. データ構造」Python 3.14 ドキュメント(2026年8月確認)

問30|挿入と削除

幅0のスライスへの代入と del を続けて行う。次のコードの実行結果はどれか。

y = [1, 2, 3]y[1:1] = [7, 8]del y[0]print(y)
  1. [1, 7, 8, 3]
  2. [2, 3, 7, 8]
  3. [7, 8, 3]
  4. [7, 8, 2, 3]
正解と解説
正解:D. [7, 8, 2, 3]

y[1:1] は幅0の範囲なので、そこへの代入は削除を伴わない挿入になり、リストは [1, 7, 8, 2, 3] になる。続く del y[0] は先頭の 1 を取り除くので [7, 8, 2, 3] が残る。挿入のときに元の要素も1つ消えると読むと 7 8 3 の形になり、del が別の位置を消すと考えると先頭の 1 が残る形になる。末尾に足されたと読み違えると 2 と 3 が先に来る形になる。del は文なので戻り値が無く、値も取り出さずに削除する点も押さえておきたい。

根拠:Python Software Foundation「Python チュートリアル 5. データ構造」Python 3.14 ドキュメント(2026年8月確認)

問31|getの既定値

辞書に無いキーを get で引いた。次のコードを実行したとき出力される内容はどれか。

d = {"a": 1, "b": 2}print(d.get("z"), d.get("z", 0))
  1. None と 0 がこの順に出力される
  2. 0 と 0 がこの順に出力される
  3. None と None がこの順に出力される
  4. 1つ目で KeyError が送出される
正解と解説
正解:A. None と 0 がこの順に出力される

get はキーが無いときに例外を投げず、第2引数を省略していれば None を、渡していればその値を返す。したがって1つ目は None、2つ目は 0 になる。第2引数が無いときも 0 が返ると考えると両方 0 になり、第2引数が無視されると考えると両方 None になる。角括弧で d["z"] と書けば KeyError になるが、それを避けるための道具が get である。

根拠:Python Software Foundation「Python チュートリアル 5. データ構造」Python 3.14 ドキュメント(2026年8月確認)

問32|setdefault

setdefault を、既にあるキーと無いキーの両方に対して呼んだ。次のコードの出力はどれか。

d = {"a": 1}print(d.setdefault("a", 99))print(d.setdefault("b", 99))print(d)
  1. 1 と None のあと {'a': 1, 'b': None} が出力される
  2. 1 と 99 のあと {'a': 1, 'b': 99} が出力される
  3. 99 と 99 のあと {'a': 99, 'b': 99} が出力される
  4. 1 と 99 のあと {'a': 1} が出力される
正解と解説
正解:B. 1 と 99 のあと {'a': 1, 'b': 99} が出力される

setdefault は、キーがあれば既存の値を返すだけで辞書を変えない。キーが無ければ第2引数を値として挿入し、その値を返す。よって1回目は既存の 1 が返って辞書はそのまま、2回目は 99 が挿入されて 99 が返る。既存の値まで上書きされると考えると両方 99 になる形になり、挿入が起きないと考えると辞書が増えない形になる。第2引数を省略すると挿入される値は None になるので、None が入る形は第2引数を書かなかった場合の結果である。

根拠:Python Software Foundation「Python チュートリアル 5. データ構造」Python 3.14 ドキュメント(2026年8月確認)

問33|inが見る所

辞書に対する in 演算子が何を調べているかを確かめる。次のコードの出力はどれか。

d = {"x": 1, "y": 2}print("x" in d, 1 in d, 1 in d.values())
  1. True False False がこの順に出力される
  2. False True True がこの順に出力される
  3. True False True がこの順に出力される
  4. True True True がこの順に出力される
正解と解説
正解:C. True False True がこの順に出力される

辞書に対する in はキーだけを調べる。"x" はキーにあるので True、1 は値としては存在するがキーには無いので False になる。値を調べたいときは d.values() を対象にすればよく、こちらは True になる。in が値も見ると考えるとすべて True になり、values() を対象にしても値を見ないと考えると最後が False になる。キーと値の役割を入れ替えて読むと先頭が False になる。キーの有無を確かめてから角括弧で引く、という使い方が定番である。

根拠:Python Software Foundation「Python チュートリアル 5. データ構造」Python 3.14 ドキュメント(2026年8月確認)

問34|キーの重複

辞書のリテラルの中に同じキーを2度書いた。次のコードの実行結果はどれか。

d = {"a": 1, "b": 2, "a": 3}print(d)
  1. {'a': 1, 'b': 2}
  2. {'b': 2, 'a': 3}
  3. {'a': 3, 'b': 3}
  4. {'a': 3, 'b': 2}
正解と解説
正解:D. {'a': 3, 'b': 2}

辞書のリテラルは左から順に項目を作っていくので、同じキーが2度現れると後の値が前の値を上書きする。エラーや警告にはならない。先に書いた方が残ると考えると a の値が 1 のままになる。また辞書は挿入した順序を保ち、上書きでは位置が動かないので、a が先に来る並びのままである。したがってキーの並びが入れ替わることも、b の値まで巻き添えで変わることもない。

根拠:Python Software Foundation「Python チュートリアル 5. データ構造」Python 3.14 ドキュメント(2026年8月確認)

問35|辞書の作り方

キーワード引数から作った辞書と、組の並びから作った辞書を比べる。次のコードの出力はどれか。

d1 = dict(x=1, y=2)d2 = dict([("x", 1), ("y", 2)])print(d1 == d2)print(d1)
  1. True のあとに {'x': 1, 'y': 2} が出力される
  2. False のあとに {'x': 1, 'y': 2} が出力される
  3. True のあとに {1: 'x', 2: 'y'} が出力される
  4. True のあとに [('x', 1), ('y', 2)] が出力される
正解と解説
正解:A. True のあとに {'x': 1, 'y': 2} が出力される

dict はキーワード引数からも、(キー, 値) の組の並びからも辞書を作れる。どちらの書き方でも同じ内容の辞書ができるので比較は True になる。作り方が違えば別物になると考えると比較が False になる。キーワード引数の名前がそのままキーの文字列になるので、キーと値が入れ替わることはない。dict に通した時点で辞書になっているので、組の並びのままにもならない。

根拠:Python Software Foundation「Python チュートリアル 5. データ構造」Python 3.14 ドキュメント(2026年8月確認)

問36|空の波括弧

空の波括弧と set() の型を比べる。次のコードを実行したとき、表示される2つの型名はどれか。

a = {}b = set()print(type(a).__name__, type(b).__name__)
  1. set と dict がこの順に出力される
  2. dict と dict がこの順に出力される
  3. dict と set がこの順に出力される
  4. set と set がこの順に出力される
正解と解説
正解:C. dict と set がこの順に出力される

要素の入った {1, 2} は集合になるが、中身が空だと辞書とも集合とも決められない。Python はこの場合を辞書として扱うので、{} は空の辞書である。空の集合が欲しいときは set() と書くしかない。波括弧なら常に集合だと考えると両方 set になり、2つを取り違えると順序が逆になる。set() まで辞書になると考えると両方 dict になる。集合と辞書はどちらも波括弧を使うため、この区別は取り違えやすい。

根拠:Python Software Foundation「Python チュートリアル 5. データ構造」Python 3.14 ドキュメント(2026年8月確認)

問37|集合の演算

2つの集合に積集合と対称差の演算を行った。次のコードの出力はどれか。

s1 = {1, 2, 3, 4}s2 = {3, 4, 5}print(sorted(s1 & s2), sorted(s1 ^ s2))
  1. [3, 4] と [1, 2, 3, 4, 5] がこの順に出力される
  2. [3, 4] と [1, 2, 5] がこの順に出力される
  3. [3, 4] と [1, 2] がこの順に出力される
  4. [1, 2, 5] と [3, 4] がこの順に出力される
正解と解説
正解:B. [3, 4] と [1, 2, 5] がこの順に出力される

アンパサンドは積集合で、両方にある 3 と 4 が残る。ハットは対称差で、どちらか一方にしか無い要素を集めるので、s1 だけにある 1 と 2、s2 だけにある 5 が残り、共通の 3 と 4 は落ちる。対称差を差集合と取り違えると 5 が抜けた形になり、2つの演算を入れ替えると出力の順序が逆になる。対称差を和集合と取り違えると 3 と 4 まで含む形になる。集合の表示順は決まっていないので、ここでは sorted で並べて確かめている。

根拠:Python Software Foundation「Python チュートリアル 5. データ構造」Python 3.14 ドキュメント(2026年8月確認)

問38|重複の除去

重複のあるリストを集合に通した。次のコードを実行したときの出力はどれか。

data = [3, 1, 3, 2, 1, 1]print(len(set(data)), sorted(set(data)))
  1. 3 と [1, 2, 3] がこの順に出力される
  2. 6 と [1, 2, 3] がこの順に出力される
  3. 3 と [3, 1, 2] がこの順に出力される
  4. 6 と [3, 1, 3, 2, 1, 1] がこの順に出力される
正解と解説
正解:A. 3 と [1, 2, 3] がこの順に出力される

set にリストを渡すと重複が取り除かれ、残る値は 1・2・3 の3種類になるので長さは 3 である。sorted に集合を渡すと昇順に並んだ新しいリストが返る。重複が残ると考えると個数が 6 になる形になる。sorted は元の出現順ではなく大小で並べ替えるので、最初に現れた順に並ぶこともない。集合そのものの表示順に意味は無いため、並べたいときは sorted を通す。

根拠:Python Software Foundation「Python チュートリアル 5. データ構造」Python 3.14 ドキュメント(2026年8月確認)

問39|要素の条件

集合にタプルとリストを順に追加しようとした。次のコードを実行するとどうなるか。

s = set()s.add((1, 2))s.add([3, 4])print(len(s))
  1. ValueError になり、要素の型が混在できない
  2. TypeError になり、リストは集合に入れられない
  3. 2 が出力され、どちらの要素も集合に入る
  4. 1 が出力され、リストはタプルに変換される
正解と解説
正解:B. TypeError になり、リストは集合に入れられない

集合の要素と辞書のキーはハッシュ可能でなければならない。タプルは中身を変えられないのでハッシュ可能であり追加できるが、リストは後から中身が変わりうるためハッシュ可能ではなく、unhashable type というメッセージの TypeError になる。どちらも入ると考えると 2 が出力される形になり、暗黙にタプルへ変換されると考えると 1 が出力される形になる。型が混在すること自体は問題ではないので、ValueError になるという理由付けも誤りである。

根拠:Python Software Foundation「Python チュートリアル 5. データ構造」Python 3.14 ドキュメント(2026年8月確認)

問40|3つの取出し

辞書のメソッド keys values items がそれぞれ何を返すかの組合せとして適切なものはどれか。

  1. keys は値、values はキー、items は値どうしの組を返す
  2. keys はキーと値の組、values はキー、items は値を返す
  3. keys は値の組、values はキーの組、items は項目数を返す
  4. keys はキー、values は値、items はキーと値の組を返す
正解と解説
正解:D. keys はキー、values は値、items はキーと値の組を返す

keys はキーだけ、values は値だけ、items は (キー, 値) というタプルを順に返す。辞書を見て回るときは for k, v in d.items() と2つの変数で受けるのが定型である。3つの役割を入れ替えて覚えていると、keys が値を返すといった説明になる。items が返すのは項目の並びであって個数ではないので、項目数を返すという説明も誤りであり、個数を知りたいときは len を使う。なお辞書をそのまま for に渡すとキーが取り出される。

根拠:Python Software Foundation「Python チュートリアル 5. データ構造」Python 3.14 ドキュメント(2026年8月確認)

演習:この章の問題を解く

ランダム出題の演習ツールです(JavaScript が有効な場合に動きます)。上の「確認問題」はそのままでもすべて読めます。

※ 解説は学習用の情報提供です。最新の出題範囲・制度は必ず公式発表をご確認ください。
※ 出題は、AWS公式ドキュメント・試験ガイド、JDLA「G検定 試験出題範囲(シラバス2024)第1.4版」、一般社団法人Pythonエンジニア育成推進協会の公開情報とPython公式ドキュメントに沿った仮の宿 学習室のオリジナル問題です(2026年8月時点で確認)。Pythonの問題はすべて実行して確認しています。試験制度・出題範囲は各実施団体の公式発表をご確認ください。