受講方法(再掲) 正しい、または、誤り、である問題の文章が表示されます。
正しいか誤りか考えた上で、問題の下にある回答を押してください。回答はリスト形式になっており、押下すると開きます。
解説を読んでいただき、次の問題に進んでください。
・プライバシーポリシーと免責 本サイトはブラウザのCookieを使用しています。 個人情報を利用することはありません。 本サイトは合格を約束するものではありません。 管理者はいかなる責任も負いかねます。
前のステップはこちら 基礎・初級 問題41
タプルはイミュータブルなデータ構造であるため、一度作成したタプルの要素を後から書き換えようとするとエラー(TypeError)が発生する。
回答・解説
arrow_drop_up クリックで開きます
〇正しい
その通りです。Pythonのタプル(tuple)は「イミュータブル(不変)」、つまり一度作成したら中身を変更できない という性質を持っています。
実際にエラーになる例 リスト([])とタプル(())を比較してみると、その違いがよく分かります。
Python
# リストの場合(ミュータブル:変更可能)
my_list = [1, 2, 3]
my_list[0] = 100 # これはOK
# タプルの場合(イミュータブル:変更不可)
my_tuple = (1, 2, 3)
my_tuple[0] = 100 # ここで TypeError が発生!
なぜ「変更できない」ものがあるのか? 一見不便に思えるかもしれませんが、イミュータブルであることには以下のようなメリットがあります。
安全性が高い : プログラムの途中でうっかり値が書き換わってしまうのを防げます(定数のような扱い)。
辞書のキーにできる : 変更されないことが保証されているため、辞書の「キー」として使うことができます(リストは変更可能なため、キーには使えません)。
処理が速い : 変更を考慮しなくてよいため、リストよりもメモリ使用量が少なく、読み込み速度もわずかに高速です。
問題42
辞書(dict)において、値(value)にはリストや別の辞書を格納できるが、キー(key)にはリストのようなミュータブルなオブジェクトを指定することはできない。
回答・解説
arrow_drop_up クリックで開きます
〇正しい
辞書のキー(key)には、「ハッシュ可能(Hashable)」であるオブジェクト、つまり中身が変更されない(イミュータブルな)オブジェクト しか使えません。
一方で、値(value) には何の制限もなく、リスト、辞書、あるいは自作のオブジェクトなど、あらゆるものを格納できます。
なぜキーにリストが使えないのか? 辞書は「キー」を元に内部で「ハッシュ値」という計算を行い、データがどこにあるかを高速に見つけ出します。もしキーであるリストの中身が途中で変わってしまうと、その計算結果が狂ってしまい、データを探し出せなくなるため、Pythonではリストをキーにすることを禁止しています。
比較例 Python
# --- 値(value)にリストを使うのはOK ---
my_dict = {"fruits": ["apple", "banana"]}
# --- キー(key)にリストを使うのはNG ---
bad_dict = {[1, 2]: "numbers"}
# 実行すると TypeError: unhashable type: 'list' が発生します
キーに使えるもの・使えないもの 種類
使える(イミュータブル)
使えない(ミュータブル)
基本型
数値(10)、文字列("name")
なし
集合型
タプル (1, 2)
リスト [1, 2]
辞書 {"a": 1}
問題43
次のコードを実行したとき、 10 が出力され、その後[20, 30] が出力される。
Python
data = [10, 20, 30]
removed = data.pop(0)
print(removed)
print(data)回答・解説
arrow_drop_up クリックで開きます
〇正しい
このコードを実行すると、最初に 10 が出力され、次に [20, 30] が出力されます。
この挙動を理解するカギは、リストの pop() メソッドが持つ「2つの役割」 にあります。
pop() メソッドの2つの役割要素の削除 : 指定した位置(インデックス)にある要素を、元のリストから取り除きます。
値の返却 : 削除したその値を「戻り値」として返します。
動作を分解してみましょう data.pop(0): インデックス 0(一番左)にある 10 をリストから抜き取ります。
removed = ...: 抜き取られた 10 という値が、変数 removed に代入されます。
data の中身 : 10 が抜き取られたため、リストには [20, 30] だけが残ります。
補足:引数を省略した場合 もし data.pop() と、カッコの中に何も書かずに実行した場合は、リストの一番後ろの要素 (この場合は 30)が取り出されます。
Python
data = [10, 20, 30]
last_item = data.pop() # 引数なし
print(last_item) # 30
print(data) # [10, 20]
問題44
pop() メソッドに引数を指定しなかった場合(例:num.pop())、リストの先頭(インデックス 0)の要素が削除される。
回答・解説
arrow_drop_up クリックで開きます
×誤り
pop() メソッドに引数を指定しなかった場合、削除されるのはリストの「先頭」ではなく、「末尾(一番最後)」 の要素です。
動作の比較 なぜ末尾がデフォルトなのか? コンピュータの処理効率の面で、リストの末尾を操作する方が、先頭を操作するよりも圧倒的に高速 だからです。
実行例 Python
num = [10, 20, 30]
# 引数なしで実行
last_val = num.pop()
print(last_val) # 30(末尾が取り出される)
print(num) # [10, 20]
先頭の要素を効率よく(高速に)取り出す必要がある場合は、標準ライブラリの collections.deque(デック)という特別なデータ構造を使うのが一般的です。
問題45
次のコードを実行したとき、出力結果は [0, 4, 16] となる。
Python
squares = [x ** 2 for x in range(5) if x % 2 == 0]
print(squares)回答・解説
arrow_drop_up クリックで開きます
〇正しい
このコードを実行すると、出力結果は [0, 4, 16] となります。
これは、リストを簡潔に生成できる「リスト内包表記」 という書き方に、さらに if による条件分岐 が組み合わさったものです。
動作の仕組み この 1 行の中では、以下のステップが同時に行われています。
範囲の指定 : range(5) により、0, 1, 2, 3, 4 という数値が順番に x に取り出されます。
条件判定 ( if x % 2 == 0) : 取り出された x が「2で割り切れるか(=偶数か)」をチェックします。
$0^2 = 0$
$2^2 = 4$
$4^2 = 16$
普通の for 文で書いた場合 同じ処理を for 文で書くと以下のようになります。内包表記がいかに短く書けるかがわかりますね。
Python
squares = []
for x in range(5):
if x % 2 == 0:
squares.append(x ** 2)
問題46
次のAとBのコードの実行結果は同じである。
A:
Python
res = [i * 10 for i in range(3)]
B:
Python
res = []
for i in range(3):
res.append(i * 10)回答・解説
arrow_drop_up クリックで開きます
○正しい
問題に記載されているAとBのコードは、どちらも「0、10、20」という数字が入ったリストを作成するもので、実行結果は全く同じになります。
Aのコードで使われている書き方は「リスト内包表記」と呼ばれます。これはリストを新しく作るためのPython独特の便利なショートカットのような書き方です。
Bのコードは、空のリストを準備してから「for文」を使って1つずつ計算結果を追加していく、より標準的な書き方です。
どちらのコードを実行しても、変数 res の中身は以下のようになります。
Python
[0, 10, 20]
リスト内包表記を使うと、Bのように数行かかる処理をAのように1行でスッキリと書くことができるため、Pythonではよく使われるテクニックです。
問題47
次のAとBのコードを実行した結果は同じである。
A:
Python
res = [i * 10 for i in range(3)]
B:
Python
res = (i * 10 for i in range(3))回答・解説
arrow_drop_up クリックで開きます
✕ 誤り
AとBの結果は異なります。見た目は似ていますが、計算されたデータの「持ち方」が全く違うからです。
Aは「リスト内包表記」と呼ばれ、結果を [0, 10, 20] という一つの「リスト(データの集まり)」として作成します。そのため、中身をすぐに全部見ることができます。
対してBは「ジェネレータ式」と呼ばれます。これは中身を一度に作るのではなく「次に何を取り出すか」というルールだけを保存した特殊なオブジェクト(ジェネレータ)を作成します。
それぞれの結果を print 関数で表示してみると、違いがよくわかります。
Python
# Aの結果を表示
res_a = [i * 10 for i in range(3)]
print(res_a)
# 出力: [0, 10, 20] (中身が見える)
# Bの結果を表示
res_b = (i * 10 for i in range(3))
print(res_b)
# 出力: (中身ではなく、データの生成器であることが表示される)
このように、Aは「完成品が入った箱」、Bは「これからデータを作る機械」のような違いがあるため、実行結果は同じとは言えません。
問題48
次のコードを実行したとき、結果として [1, 3] が出力される。
Python
num = [1, 2, 3]
del num[1]
print(num)回答
arrow_drop_up クリックで開きます
○正しい
このコードを実行すると、結果として [1, 3] が出力されます。
コードの中で使われている del という命令は、リストの中の指定した位置にある要素を削除するためのものです。Pythonのリストでは、中身の順番を 0 から数え始めるという決まりがあります。
今回のコードの流れを追ってみましょう。
まず、num というリストには 1(0番目)、2(1番目)、3(2番目)という数字が入っています。
次に、del num[1] を実行することで、1番目の位置にある「2」が削除されます。
その結果、リストには「1」と「3」だけが残り、print(num) で [1, 3] が表示されることになります。
Python
num = [1, 2, 3] # [0番目, 1番目, 2番目]
del num[1] # 1番目の「2」を消す
print(num) # 残った [1, 3] が表示される
もし del num[0] と書いた場合は、最初の「1」が消えて [2, 3] が出力されるようになります。
問題49
次のコードを実行したとき、NameError が発生する。
Python
num = [1, 2, 3, 4, 5]
del num[1:4]
print(num)回答・解説
arrow_drop_up クリックで開きます
✕誤り
このコードを実行しても NameError は発生せず、正常に処理が完了して [1, 5] という結果が出力されます。
NameError は、定義されていない変数名を使おうとしたときに「そんな名前の変数は見当たりません」というエラーとして発生するものです。今回のコードでは num という変数が正しく作られているため、このエラーは起きません。
コードの中で使われている del num[1:4] は「スライス」という機能を使った削除方法です。
num[1:4] は「1番目から4番目の手前まで(つまり1番目、2番目、3番目)」という範囲を指定しています。
具体的にリストの中身の動きを見てみましょう。
0番目:1
1番目:2
2番目:3
3番目:4
4番目:5
このうち、1番目から3番目にあたる「2, 3, 4」がまとめて削除されます。
Python
num = [1, 2, 3, 4, 5]
del num[1:4] # 1番目から4番目の手前(2, 3, 4)を消す
print(num) # 残った [1, 5] が表示される
問題50
次のコードを実行したとき、出力結果は [10, 20, 10, 30] となる。
Python
data = [10, 20, 10, 30]
print(data)回答・解説
arrow_drop_up クリックで開きます
○正しい
このコードを実行すると、出力結果は [10, 20, 10, 30] となります。
Pythonのリスト([]で囲まれたデータの集まり)には、同じ値を重複して含めることができるという特徴があります。今回の data というリストには 10 が2回登場していますが、これはエラーにはならず、そのままの順番で保存されます。
コードの流れは非常にシンプルです。
まず、10, 20, 10, 30 という4つの数字を順番に並べたリストを作成し、それを data という名前の変数に入れています。
次に、print(data) を実行することで、その中身をそのまま画面に表示しています。
Python
data = [10, 20, 10, 30]
print(data) # リストの中身がそのまま [10, 20, 10, 30] と表示される
もし「重複した値を自動的に取り除きたい」という場合には、リストではなく「セット(集合)」という別の仕組みを使うことになりますが、今回のリスト形式では書いた通りの内容が出力されます。
問題51
次のコードを実行したとき、出力される集合の要素数は 3 つである。
Python
colors = {'red', 'blue'}
colors.add('red')
colors.add('green')
print(colors)回答・解説
arrow_drop_up クリックで開きます
○正しい
このコードを実行したとき、画面に表示される集合(セット)の中身は3つになります。
Pythonの「集合(set)」には、数学の集合と同じように「同じ値(重複した値)を1つにまとめる」という大きな特徴があります。
コードの動きを順番に追ってみましょう。
最初に、{'red', 'blue'} という2つの要素が入った集合を作っています。
次に、colors.add('red') を実行して 'red' を追加しようとしますが、すでに集合の中に 'red' が存在しているため、新しく追加されることはなく、変化しません。
最後に、colors.add('green') を実行すると、これはまだ集合にないので新しく追加されます。
最終的な colors の中身は {'red', 'blue', 'green'} の3つになります。
Python
colors = {'red', 'blue'}
colors.add('red') # すでにあるので増えない
colors.add('green') # 新しく追加される
print(colors) # 要素数は3つ
なお、集合はリストと違って「順番」を管理しないため、表示されるときの並び順は {'green', 'red', 'blue'} のように変わることがありますが、中身の数は必ず3つです。
問題52
次のコードを実行したとき、変数 x のデータ型は集合(set)である。
Python
x = {}
print(type(x))回答・解説
arrow_drop_up クリックで開きます
✕誤り
このコードを実行したとき、変数 x のデータ型は集合(set)ではなく、辞書(dict)になります。
Pythonでは、波カッコ {} を使って「集合(set)」と「辞書(dict)」の両方を表しますが、中身が空っぽの状態({})で作成すると、Pythonはそれを「辞書」として扱う決まりになっています。
もし空の「集合」を作りたい場合は、{} ではなく set() と書く必要があります。
それぞれの違いをコードで見ると以下のようになります。
Python
x = {}
print(type(x)) # (辞書型)
y = set()
print(type(y)) # (集合型)
辞書は「名前:値」というペアを管理するためのもので、集合は「値」だけを管理するものです。中身が入っている場合は、x = {1, 2} なら集合、x = {'a': 1} なら辞書というように、書き方で自動的に判別されますが、空のときだけは注意が必要です。
問題53
次のコードを実行したとき、出力結果は 3 となる。
Python
data = {'a': 1, 'b': 2}
data['a'] = 3
print(data['a'])回答・解説
arrow_drop_up クリックで開きます
○正しい
このコードを実行すると、出力結果は 3 となります。
このコードで使われているのは「辞書(dict)」という、ラベル(キー)と値がセットになったデータの管理方法です。
コードの流れを詳しく見てみましょう。
まず、data = {'a': 1, 'b': 2} という部分で、'a' という名札に 1、'b' という名札に 2 という値をセットにした辞書を作っています。
次に、data['a'] = 3 を実行しています。これは「'a' という名札の値を 3 に書き換えてください」という命令です。これにより、もともと 1 だった値が 3 に更新されます。
最後に、print(data['a']) で 'a' の中身を表示させているため、書き換えられた後の 3 が出力されます。
Python
data = {'a': 1, 'b': 2}
data['a'] = 3 # 'a'の値を 1 から 3 に上書き
print(data['a']) # 3 が表示される
辞書はリストと違って「0番目、1番目」という番号ではなく、'a' や 'b' といった好きな名前(キー)を使ってデータを管理できるのがとても便利なポイントです。
問題54
次のコードを実行したとき、画面には Python という文字が3回出力される。
Python
for i in range(1, 3):
print('Python')回答・解説
arrow_drop_up クリックで開きます
×誤り
このコードを実行したときに画面に出力される「Python」という文字は2回です。
range(1, 3) という命令は、1から始まって3の「手前」までの数字を順番に用意します。つまり、1と2の合計2回分しか処理が行われません。
もし「Python」と3回表示させたい場合は、range(1, 4) のように終わりの数字を一つ大きくするか、range(3) のように書く必要があります。
以下のコードを実行すると、実際に2回だけ表示されることが確認できます。
Python
for i in range(1, 3):
print('Python')
この問題のポイントは、range関数の終わりの数値はその数字自体を含まないという点です。
問題55
辞書にループをかけて、キーと値を同時に取得するときに使うメソッドはpack()である。
回答・解説
arrow_drop_up クリックで開きます
×誤り
辞書(dict)からキーと値の両方を同時に取り出してループ処理を行いたいときに使うメソッドは、pack() ではなく items() です。
Pythonにおいて「パック(pack)」という言葉は、複数の値を一つの変数にまとめる際などに使われますが、辞書のループ処理で使う専用のメソッド名ではありません。items() メソッドを使うと、一つのペア(キーと値)をセットにして取り出すことができます。
正しい書き方は以下のようになります。
Python
scores = {'数学': 80, '英語': 90}
for subject, point in scores.items():
print(subject, 'は', point, '点です')
このコードを実行すると「数学 は 80 点です」「英語 は 90 点です」と表示されます。もし values() というメソッドを使えば「値」だけを、何も書かなければ「キー」だけを取り出すことになります。
問題56
次のコードを実行したとき、出力結果は True である。
Python
result = True or False and False
print(result)回答・解説
arrow_drop_up クリックで開きます
○正しい
この問題のポイントは、or(論理和)と and(論理積)が混ざっているとき、どちらが先に計算されるかという「優先順位」にあります。
算数で「たし算」よりも「かけ算」を先に計算するのと同じように、Pythonの論理演算では or よりも and を先に計算するというルールがあります。
このコードの計算順序を整理すると以下のようになります。
まず、後ろ側の「False and False」が計算されます。and は両方が True のときだけ True になる演算なので、ここは False になります。
次に、残った「True or (1の結果)」を計算します。つまり「True or False」となります。
or はどちらか一方が True であれば結果が True になる演算なので、最終的な結果は True になります。
もし or を先に計算してしまうと結果が変わってしまいますが、Pythonでは必ず and が優先されることを覚えておきましょう。
Python
# 実際の計算イメージ
result = True or (False and False) # ここが先に計算される
# result = True or False
# result = True
問題57
次のコードを実行したとき、出力結果は False である。
Python
result = not 10 == 20
print(result)回答・解説
arrow_drop_up クリックで開きます
✕誤り
このコードを実行すると、出力結果はTrue になります。
Pythonでは「==(比較)」の方が「not(否定)」よりも先に計算されます。
まず「10 == 20」の部分が計算されます。10と20は等しくないので、この結果は False になります。
次に「not False」が計算されます。notは値を反対にする命令なので、False の反対である True が最終的な結果となります。
Python
result = not 10 == 20
# 1. 10 == 20 を計算 → False
# 2. not False を計算 → True
print(result) # True が表示される
問題58
次のコードを実行したとき、出力結果は True である。
Python
result = 5 + 3 < 10
print(result)回答・解説
arrow_drop_up クリックで開きます
〇正しい
このコードを実行すると、出力結果は True になります。
この問題のポイントは、計算の「優先順位」です。Pythonでは、足し算(+)などの計算は、大きさを比べる記号(<)よりも先に処理されます。
具体的には、まず「5 + 3」が計算されて「8」になります。その後に「8 < 10(8は10より小さいか?)」というチェックが行われます。
8は10よりも小さいため、結果として「正しい」を意味する True が変数 result に代入されます。
Python
result = 5 + 3 < 10
# 1. まず 5 + 3 を計算して 8 になる
# 2. 8 < 10 を判定する
# 3. 正しいので result は True になる
print(result)
もし、計算の優先順位がわからなくなった場合は、カッコを使って計算順序をはっきりさせることもできます。
Python
result = (5 + 3) < 10
print(result)
問題59
main.pyを実行したとき、関数 add は calc. という接頭辞なしで直接呼び出すことができ、標準出力に「30」が表示される。
calc.py
def add(a, b):
return a + bmain.py
from calc import add
result = add(10, 20)
print(result) 回答・解説
arrow_drop_up クリックで開きます
○正しい
このコードは正しく動作し、画面には「30」と表示されます。
通常、別のファイル(モジュール)にある関数を使うときは「ファイル名.関数名()」と書く必要があります。しかし、今回のように「from calc import add」と書くことで、「calcファイルの中からadd関数だけを直接持ってきて使う」という指定になります。
そのため、プログラムの中では「calc.add」と書かずに、そのまま「add」と書くだけで使うことができるようになります。
計算の流れは以下の通りです。
from calc import add によって add 関数が読み込まれる
add(10, 20) が実行され、10 + 20 の結果である 30 が返ってくる
print(result) によって 30 が表示される
Python
# main.py の中身
from calc import add
result = add(10, 20)
print(result) # 30 が表示される
問題59
次の記述は、mathモジュールからsqrt関数とsin関数のみをインポートする正しい構文である。
Python
from math import sqrt, sin回答・解説
arrow_drop_up クリックで開きます
〇正しい
この記述は、mathモジュールの中から特定の関数(sqrtとsin)だけを選んで使えるようにする正しい書き方です。
通常、モジュール内の機能を使うときは「math.sqrt()」のように「モジュール名.関数名」と書く必要がありますが、この「from ... import ...」という書き方を使うと、モジュール名を省略して直接「sqrt()」や「sin()」と書けるようになります。
複数の関数を取り込みたいときは、この問題のようにカンマで区切って並べることができます。
Python
from math import sqrt, sin
# モジュール名をつけずに直接関数を使えます
print(sqrt(16)) # 16の平方根なので 4.0
print(sin(0)) # 0の正弦(サイン)なので 0.0
他に取り込みたい関数が増えた場合も、後ろにカンマを続けて書き足すだけで対応可能です。
問題60
あるモジュールが定義している関数をすべて取り込む記述はfrom * import funcである。
回答・解説
arrow_drop_up クリックで開きます
✕誤り
あるモジュールからすべての関数を取り込みたい場合は、記述の前後が逆で「from モジュール名 import *」と書くのが正しいルールです。
アスタリスク(*)は「すべて」という意味を持っており、この書き方をすることでそのモジュールに入っている関数や変数を一気にまとめて取り込むことができます。問題文にある「import func」としてしまうと、funcという名前の特定の機能だけを探しに行ってしまうため、すべての機能を取り込むことはできません。
Python
# 正しい書き方の例(mathモジュールの機能をすべて取り込む場合)
from math import *
# math. をつけなくても、sqrtなどの関数がいきなり使えます
print(sqrt(25))
ただし、この書き方をすると自分で作った変数名とモジュール内の名前がぶつかってしまう可能性があるため、初心者のうちは必要なものだけを個別にインポートするのがおすすめされています。
問題61
次のコードを実行したとき、出力結果は Age is 20 となる。
Python
age = 20
print(f'Age is {age}')回答・解説
arrow_drop_up クリックで開きます
〇正しい
この記述は「f文字列(フォーマット済み文字列リテラル)」と呼ばれる便利な機能を使った正しい書き方です。
文字列の先頭に f をつけ、文字列の中で変数を波カッコ { } で囲むと、その部分が変数の値に置き換わります。この問題では、age という変数に 20 が代入されているため、{age} の部分が 20 に変換されて、画面には Age is 20 と表示されます。
Python
age = 20
# 波カッコの中身が実行時に書き換わります
print(f'Age is {age}')
もし f を忘れて print('Age is {age}') と書いてしまうと、波カッコがそのまま文字として扱われ、Age is {age} と出力されてしまうので注意が必要です。
問題62
次のコードを実行したとき、エラーになる。
Python
print('{1} and {0}'.format('Orange', 'Apple'))回答・解説
arrow_drop_up クリックで開きます
✕誤り
このコードを実行してもエラーにはならず、正しく実行されます。
Pythonの文字列にある「format」という機能では、カッコの中に並べたデータに、左から順番に「0番目、1番目、2番目…」と番号が割り振られます。この問題の例では以下のようになります。
0番目:'Orange'
1番目:'Apple'
文字列の中にある {1} や {0} は「ここに○番目のデータを入れてください」という指定です。
Python
# {1} の場所に 1番目の 'Apple'、{0} の場所に 0番目の 'Orange' が入ります
print('{1} and {0}'.format('Orange', 'Apple'))
その結果、画面には Apple and Orange と表示されます。指定する番号がデータの数を超えていなければ、順番を入れ替えて表示させることは全く問題ありません。
もし print('{2} and {0}'.format('Orange', 'Apple')) のように、存在しない「2番目」を指定した場合にはエラーになります。
問題63
次のコードのように、文字列と数値を + 演算子で直接結合しようとするとエラー(TypeError)が発生する。
Python
count = 5
print('Count: ' + count)回答・解説
arrow_drop_up クリックで開きます
〇正しい
Pythonでは、文字列(str型)と数値(int型)を「+」記号で直接つなげようとすると、型が違うためにエラー(TypeError)が発生します。
「+」演算子は、相手が両方とも「数値」なら足し算を行い、両方とも「文字列」なら文字の連結を行います。しかし、このコードのように「文字列 + 数値」という組み合わせになると、コンピュータは足し算をすべきか連結をすべきか判断できず、処理を止めてしまいます。
正しく表示させるためには、数値を str() という機能を使って文字列に変換する必要があります。
Python
count = 5
# str(count) とすることで、5 を '5' という文字に変換して連結できます
print('Count: ' + str(count))
このように型を揃えてあげることで、エラーを出さずに「Count: 5」と表示させることができます。
問題64
以下のコードを実行してエラーが発生した際、◆の箇所には#が表示される。
コード
-------------------------------
while True print('error'):
-------------------------------
エラー
-------------------------------
File "", line 1
while True print('error'):
◆
------------------------------- 回答・解説
arrow_drop_up クリックで開きます
✕誤り
Pythonが文法ミス(SyntaxError)を見つけたときに表示される記号は、# ではなく ^(キャレット)です。
このエラーは「構文エラー」と呼ばれるもので、プログラムの書き方のルールが間違っているときに発生します。Pythonは「ここがおかしいよ!」と教えてくれる際、エラーの原因と思われる箇所のすぐ下に ^ 記号を表示して指し示してくれます。
問題のコードでは、while文の条件式の後にあるべきコロン(:)が抜けているため、そこでエラーが発生します。
Plaintext
File "", line 1
while True print('error'):
^
SyntaxError: invalid syntax
このように、矢印のような形で間違いの場所を教えてくれるのが特徴です。# 記号はPythonでは「コメントアウト(プログラムとして無視する部分)」を作るために使われる記号なので、エラー箇所の指摘には使われません。
問題65
以下のコードを実行したとき、ZeroDivisionError が発生する。
Python
try:
result = 10 / 0
except ZeroDivisionError:
print('Error occurred')
print('End')回答・解説
arrow_drop_up クリックで開きます
✕誤り
このコードを実行しても、プログラム全体が停止して「ZeroDivisionError」というエラー画面(トレースバック)が出ることはありません。
Pythonには「例外処理」という仕組みがあり、try ブロックの中でエラーが起きても、それを except ブロックで捕まえて別の処理に切り替えることができます。今回のコードでは、10 / 0 という「0での割り算」が行われた瞬間に ZeroDivisionError が発生しますが、すぐに下の except ZeroDivisionError: がそのエラーをキャッチします。
そのため、エラーで止まる代わりに「Error occurred」というメッセージが表示され、その後もプログラムは動き続けて「End」と表示されます。
Python
try:
result = 10 / 0 # ここでエラーが発生!
except ZeroDivisionError:
# エラーを捕まえて、ここの処理を実行します
print('Error occurred')
print('End') # プログラムは止まらずにここまで実行されます
もし try や except を使わずに result = 10 / 0 だけを書いた場合は、「ZeroDivisionError」が発生してプログラムが強制終了してしまいます。
問題66
Pythonには構文エラーと例外があるがIndentationError、ZeroDivisionError、NameErrorは例外にあたる。
回答・解説
arrow_drop_up クリックで開きます
✕誤り
Pythonのエラーは大きく分けて「構文エラー(SyntaxError)」と「例外」の2種類がありますが、問題文にある IndentationError(インデントエラー)は、実は「構文エラー」の仲間に分類されます。
Pythonのルールとして、プログラムが動く前にチェックされる「書き方のルール違反」が構文エラーです。一方で、書き方は合っているけれど、実行してみたら計算できなかったというような問題が「例外」です。
ZeroDivisionError(ゼロで割る)や NameError(存在しない変数を使う)は、実行中に発生するため「例外」にあたります。しかし、IndentationError はコードを実行する前の解析段階で見つかるものなので、正確には構文エラーの一種となります。
以下のように、インデントがずれているとプログラムが動き出す前にエラーとして指摘されます。
Python
def hello():
print("こんにちは") # 本来はインデントが必要なため、構文エラー(IndentationError)になる
問題67
次のコードを実行すると、ZeroDivisionError が出力される。
Python
try:
result = 10 / 0
except Exception:
print('Exception')
except ZeroDivisionError:
print('ZeroDivisionError')回答・解説
arrow_drop_up クリックで開きます
✕誤り
このコードを実行したときに出力されるのは「Exception」であり、ZeroDivisionError ではありません。
Pythonの例外処理(try-except文)には、上から順番にエラーの種類をチェックし、当てはまるものがあればそれ以降のチェックは行わないというルールがあります。
さらに、エラーの種類には親子関係のような階層があります。「Exception」はほとんどの例外の親(基本となる型)であるため、その子供である「ZeroDivisionError」も「Exception」の一部として扱われてしまいます。
このコードでは、最初に except Exception が書かれているため、0で割るエラーが発生した瞬間に「これは Exception の一種だ」と判定され、その下の except ZeroDivisionError までたどり着くことができません。
意図した通りにエラーを分けたい場合は、以下のように範囲の狭い(具体的な)エラーから先に書く必要があります。
Python
try:
result = 10 / 0
except ZeroDivisionError:
# 具体的なエラーを先に書く
print('ZeroDivisionError')
except Exception:
# その他の一般的なエラーを後に書く
print('Exception')
問題68
次のコードを実行すると、Success が出力される。
Python
items = [1, 2, 3]
try:
val = items[1]
except IndexError:
print('IndexError')
else:
print('Success')回答・解説
arrow_drop_up クリックで開きます
○正しい
このコードを実行すると、画面には「Success」と表示されます。
Pythonの例外処理(try-except文)には、エラーが発生しなかったときだけ実行される「else」というブロックを作ることができます。
このコードの動きを順番に見ていきましょう。
まず、items = [1, 2, 3] というリストが作られます。次に、try ブロックの中で items[1] という値を取り出そうとしています。リストの番号は 0 から始まるので、items[1] は 2番目の要素である「2」を指しており、何も問題なく実行できます。
エラー(IndexError)が発生しなかったため、except ブロックは無視され、エラーが起きなかったときに進む else ブロックが実行されます。その結果、中にある print('Success') が動くという仕組みです。
Python
items = [1, 2, 3]
try:
# 2番目の要素「2」を取り出す(エラーなし)
val = items[1]
except IndexError:
# エラーのときはここ
print('IndexError')
else:
# エラーがなかったときはここが動く
print('Success')
もしこれが items[5] のように、存在しない番号を指定していた場合は、except の方が動いて「IndexError」と表示されます。
問題69
次のコードを実行すると、Finally は出力されない。
Python
def check_error():
try:
return 'Try'
except:
return 'Except'
finally:
print('Finally')
check_error()回答・解説
arrow_drop_up クリックで開きます
✕誤り
このコードを実行すると、「Finally」という文字は出力されます。
Pythonの例外処理(try-finally文)には非常に強力なルールがあり、finally ブロックに書かれた処理は、たとえその直前に return(関数を終了して値を返す命令)があったとしても、必ず最後に実行されます。
このプログラムの動きを順番に追いかけてみましょう。
まず、try ブロックの中で return 'Try' が実行されようとします。普通ならここで関数はすぐに終わって呼び出し元に戻りますが、finally がある場合は話が別です。Pythonは「関数を終了する前に、必ず finally の中身を片付けなさい」という動きをするため、一度 return を保留して print('Finally') を実行します。その後に、改めて return 'Try' が完了します。
Python
def check_error():
try:
# ここで戻り値が準備されるが、一旦ストップ
return 'Try'
except:
return 'Except'
finally:
# 関数の終了直前に必ずこれが実行される
print('Finally')
check_error()
このように、ファイルの保存を忘れずに行いたいときや、ネットワークの接続を確実に切りたいときなど、「何があっても絶対に最後にこれだけはやっておきたい」という処理を finally に書きます。
もし、この関数の戻り値('Try')も画面に出したい場合は print(check_error()) と書く必要がありますが、その場合でも「Finally」が先に出力され、その後に「Try」が表示されることになります。
問題70
Pythonでは、例外が送出されなければexcept節はスキップされ、try文の実行が終了する。
回答・解説
arrow_drop_up クリックで開きます
◯正しい
Pythonの「try...except文」は、エラー(例外)が起きそうな処理を試してみて、もしエラーが起きたら別の処理をさせるための仕組みです。
エラーが起きなかった場合は、用意していた「エラー用の処理(except節)」は必要ないため無視されます。そのまま次のプログラムへ進むので、問題文の内容は正しいです。
Python
try:
print("エラーは起きません")
except:
print("エラーの時だけ実行されます")
print("try文が終わったのでここに来ます")
このコードを実行すると、exceptの中身は飛ばされて、最初と最後のprintだけが表示されます。
問題71
Pythonでは、発生した例外がexcept節の名前と一致しない場合は、未処理例外となり実行が終了する。
回答・解説
arrow_drop_up クリックで開きます
✕誤り
一見正しそうに見えますが、プログラムがすぐに終了するわけではありません。
プログラムの中でエラー(例外)が発生し、そのエラーの種類が「except節」に書かれた名前と一致しなかった場合、そのエラーはさらに「外側」のtry文へと渡されます。もし最終的にどこにも一致するexcept節が見つからなかったときは、そこで初めて未処理例外としてプログラムが止まります。
以下のコードを例に説明します。
Python
try:
# ゼロで割るエラーを発生させます
1 / 0
except NameError:
# ここは「名前の間違い」用なので、ゼロ除算エラーは通り過ぎます
print("名前のエラーです")この場合、NameErrorとは一致しないため、この場所では処理されません。もしこのtry文の外側に別の適切なエラー処理があれば、プログラムは動き続けます。
前のステップはこちら 関連講座はこちら