PythonのTypeError: 'function' object is not subscriptableエラーの原因と解決策
Pythonでは、リストや文字列のような反復可能(イテラブル)オブジェクトとは異なり、関数に対してインデックス構文で値にアクセスすることはできません。
関数が反復可能なオブジェクトを返す場合でも、その値にアクセスする前に、関数の戻り値を変数に代入しておく必要があります。そうしないと、「TypeError: 'function' object is not subscriptable」というエラーが発生します。
この記事では、このエラーの意味を解説し、2つの具体的なシナリオを通じて、自分のコードでこのエラーを解決する方法を紹介します。
TypeError: 'function' object is not subscriptableとは
リストや文字列などの反復可能オブジェクトは、インデックス記法を使って個々の要素や範囲にアクセスできます。
例えば、以下のコードを見てみましょう。
grades = ["A", "A", "B"] print(grades[0])
インデックス0の位置にある値は「A」なので、このコードは「A」を出力します。しかし、この構文は関数には使えません。関数は反復可能オブジェクトではないからです。関数は、呼び出されたときにのみ反復可能なオブジェクトを返すことができます。
「TypeError: 'function' object is not subscriptable」エラーは、関数をあたかも反復可能オブジェクトであるかのようにアクセスしようとしたときに発生します。
このエラーは、主に以下の2つのシナリオでよく見られます。
- 反復可能オブジェクトと同じ名前を関数に付けた場合
- 関数を反復可能オブジェクトのように扱い、その値にアクセスしようとした場合
それでは、両方のシナリオを詳しく分析していきましょう。
シナリオ1:反復可能オブジェクトと同じ名前の関数
学校の生徒に関する情報を出力するプログラムを作成してみましょう。まず、生徒の情報と最新のテストの点数を含む辞書を定義します。
student = { "name": "Holly", "latest_test_score": "B", "class": "Sixth Grade" }
この辞書には3つのキーと3つの値があります。1つ目のキーは生徒の名前、2つ目は最新のテストで獲得した点数、3つ目は生徒が所属するクラスを表しています。
次に、これらの値をコンソールに出力する関数を定義します。
def student(pupil):
print("Name: " + pupil["name"])
print("Latest Test Score: " + pupil["latest_test_score"])
print("Class: " + pupil["class"])
このコードは、「pupil」辞書内の3つの値をコンソールに出力します。「pupil」辞書は引数としてstudent()関数に渡されます。
それでは、関数を呼び出して「student」辞書を引数として渡してみましょう。
student(student)
すると、Pythonコードはエラーをスローします。
Traceback (most recent call last):
File "main.py", line 8, in <module>
student(student)
File "main.py", line 4, in student
print("Name: " + pupil["name"])
TypeError: 'function' object is not subscriptable
このエラーの原因は、関数と反復可能オブジェクトに同じ名前が付いていることです。「student」は最初に辞書として宣言されましたが、その後同じ名前で関数を定義したため、「student」は辞書ではなく関数として扱われるようになってしまいました。
つまり、「student」を引数としてstudent()関数に渡すとき、実際に渡されているのは「student」という名前の関数なのです。
この問題は、関数名を変更することで解決できます。
def show_student_details(pupil):
print("Name: " + pupil["name"])
print("Latest Test Score: " + pupil["latest_test_score"])
print("Class: " + pupil["class"])
show_student_details(student)
関数名を「show_student_details」に変更しました。コードを実行して結果を確認してみましょう。
Name: Holly Latest Test Score: B Class: Sixth Grade
コードは正常に生徒の情報をコンソールへ出力できました。
シナリオ2:インデックス構文で関数にアクセスする
次に、生徒のレコードのリストをフィルタリングし、最新のテストでA評価を獲得した生徒だけを表示するプログラムを作成します。
まず、生徒のリストを定義します。
students = [
{ "name": "Holly", "grade": "B" },
{ "name": "Samantha", "grade": "A" },
{ "name": "Ian", "grade": "A" }
]
生徒のリストには3つの辞書が含まれています。各辞書には、生徒の名前と最新のテストで獲得した成績が格納されています。
次に、A評価を獲得した生徒のリストを返す関数を定義します。
def get_a_grade_students(pupils):
a_grade_students = []
for p in pupils:
if p["grade"] == "A":
a_grade_students.append(p)
print(a_grade_students)
return a_grade_students
この関数は「pupils」という生徒のリストを受け取ります。forループを使ってそのリストを反復処理し、特定の生徒が「A」評価を獲得している場合は、そのレコードを「a_grade_students」リストに追加します。該当しない場合は何も行いません。
すべての生徒を検索した後、コードはA評価を獲得した生徒のリストを出力し、そのリストをメインプログラムに返します。
ここで、A評価を獲得した最初の生徒を取得したいとしましょう。そのために、関数を呼び出し、インデックス構文を使って最初の生徒のレコードを取得します。
first = get_a_grade_students[0] print(first)
コードを実行すると、次のようになります。
Traceback (most recent call last): File "main.py", line 16, in <module> first = get_a_grade_students[0] TypeError: 'function' object is not subscriptable
エラーが発生しました。これは、関数をまず呼び出さずに「get_a_grade_students」関数から値を取得しようとしているためです。
この問題を解決するには、値を取得する前に、必ず先に関数を呼び出す必要があります。
a_grades = get_a_grade_students(students) first = a_grades[0] print(first)
まず、get_a_grade_students()関数を呼び出し、生徒のリストを引数として指定します。次に、インデックスを使用して、get_a_grade_students()関数が返すリストからインデックス位置0のレコードを取得します。最後に、そのレコードをコンソールに出力します。
コードを実行してみましょう。
[{'name': 'Samantha', 'grade': 'A'}, {'name': 'Ian', 'grade': 'A'}]
{'name': 'Samantha', 'grade': 'A'}
コードはまず、A評価を獲得したすべての生徒のリストを出力します。次に、そのリストの中で最初にA評価を獲得した生徒を出力します。この場合、該当する生徒はSamanthaでした。
まとめ
「TypeError: 'function' object is not subscriptable」エラーは、関数を文字列やリストのような反復可能オブジェクトであるかのように扱い、その要素にアクセスしようとしたときに発生します。
このエラーを解決するには、まず変数を宣言した後に同じ名前の関数を定義して、変数を意図せず上書きしていないことを確認してください。次に、関数が返す値にアクセスする前に、必ず関数を呼び出すようにしましょう。
これで、このよくあるPythonエラーもプロのように解決できるはずです!
-
JavaScriptのTypeError:「'undefined' is not an object」エラーの原因と対処法
「TypeError: undefined is not an object」というエラーは、値が undefined(未定義)のオブジェクトに対して、プロパティへのアクセスやメソッドの呼び出しを行った場合に発生します。 このエラーメッセージが表示されるのは Safari ブラウザのみという点に注意が必要です。Chrome や Firefox などのブラウザでは、同じ状況でも「Cannot read properties of undefined (reading xxx)」のような、少し異なる文言でエラーが出力されます。そのため、Safari でのみ発生するバグとして報告されることも多くあり
-
Pythonのissubset()関数とは?部分集合の判定方法を実例付きで解説
本記事では、Python標準ライブラリに用意されているissubset()関数の仕組みと使い方について詳しく解説します。 issubset()メソッドは、あるセット(集合)のすべての要素が、引数として渡した別のセットにも含まれている場合にブール値のTrueを返し、1つでも含まれていない要素があればFalseを返します。 下の図では、BはAの部分集合です。もしAとBが同一のセットであれば、両者は互いに部分集合の関係にあるといえます。つまり、両方のセットがまったく同じ要素を持っているということを意味します。 構文 <set 1>.issubset(<set 2>) 戻り値