Fix Python Error: 'function' Object Not Subscriptable

PYTHON Published Updated 3 mins read By Leon Wei
Fix Python Error: 'function' Object Not Subscriptable cover image

Quick summary

Summarize this blog with AI

TypeError: 'function' object is not subscriptable means the object immediately before [...] is a function. Square brackets request an item; parentheses call a function. The correction depends on the function's contract, not on adding parentheses at random.

These complete examples use Python 3.12.14. A normal Python function is callable but does not implement item access. A function can return a list, another function, a scalar, or None; inspect that value before indexing it.

Reproduce the object-versus-result mistake

def get_numbers():
    return [10, 20]

print(type(get_numbers).__name__, callable(get_numbers))
try:
    get_numbers[0]
except TypeError as exc:
    print(str(exc))
print(get_numbers()[0])

Expected output:

function True
'function' object is not subscriptable
10

The final expression is valid: it calls the function, then indexes the returned list. Splitting it into numbers = get_numbers() and numbers[0] is helpful for debugging but does not change the semantics. Calling and indexing in one expression is not inherently an error.

A successful call can still return a function

def make_reader():
    def read_values():
        return [7, 8]
    return read_values

reader = make_reader()
print(type(reader).__name__)
try:
    reader[0]
except TypeError as exc:
    print(str(exc))
values = reader()
print(values[0])

Expected output:

function
'function' object is not subscriptable
7

This is a function factory: its result is intentionally callable. Call that reader when the API says to do so. Do not create a loop that keeps calling arbitrary objects until they become lists; calls may have side effects or require arguments. If make_reader was supposed to return data directly, repair the return contract instead.

Check the binding that changed

records = [{"id": 1}]
def load_records():
    return [{"id": 2}]

records = load_records  # Rebound to the function, not its result.
print(type(records).__name__)
records = load_records()
print(records[0]["id"])

Expected output:

function
2

Trace where the name was most recently assigned. A later import, callback assignment, or local variable can replace the value you expected. Give the loader and its result distinct names. A lambda is another function object, so replacing a def with a lambda does not make it subscriptable.

After the type fix, check empty and missing results

def first_id(records):
    if not isinstance(records, list):
        raise TypeError("records must be a list")
    if not records:
        raise ValueError("records is empty")
    return records[0]["id"]

print(first_id([{"id": 4}]))
for value in [[], None, load_records]:
    try:
        first_id(value)
    except (TypeError, ValueError) as exc:
        print(type(exc).__name__, str(exc))

Expected output:

4
ValueError records is empty
TypeError records must be a list
TypeError records must be a list

This helper's narrow contract accepts a list and rejects an empty one. It does not claim to validate every row schema: a missing id still raises KeyError. A different API could deliberately return None for “not found,” in which case handle that state explicitly. Catching every TypeError and returning an empty list would conceal both programming defects and source-data problems.

Use a short diagnosis sequence

  1. Locate the exact subscript expression in the traceback.
  2. Split a long expression into named intermediate values.
  3. Inspect the type and the documented return contract without unnecessarily calling it again.
  4. Fix a missing call, an unintended function return, or a shadowed name.
  5. Test the expected sequence, empty sequence, and error return separately.

Printing type names usually avoids exposing the actual record contents. A callable test is a clue, not a universal type validator: custom objects can support both calls and indexing. The fixtures above concern ordinary Python functions.

References: Python's subscription expressions, calls, and callable. For a scalar result rather than a function, see the float subscripting guide.

Interview Prep

Begin Your SQL, Python, and R Journey

Master 230 interview-style coding questions and build the data skills needed for analyst, scientist, and engineering roles.

Related Articles

All Articles