pola-rs/polars · error · TypeError

LazyFrame is not subscriptable (aside from slicing) Use `se

Error message

LazyFrame is not subscriptable (aside from slicing)

Use `select()` or `filter()` instead.

What it means

LazyFrame does not support positional/column subscripting like DataFrame does. __getitem__ only accepts a slice object; any other key (string column name, int, tuple, list) raises TypeError because lazy evaluation cannot cheaply resolve a single column access the way an in-memory DataFrame can. Use select() for column access or filter() for row selection.

Source

Thrown at py-polars/src/polars/lazyframe/frame.py:744

        │ 2   ┆ 5   │
        └─────┴─────┘
        >>> lf[::2].collect()
        shape: (2, 2)
        ┌─────┬─────┐
        │ a   ┆ b   │
        │ --- ┆ --- │
        │ i64 ┆ i64 │
        ╞═════╪═════╡
        │ 1   ┆ 4   │
        │ 3   ┆ 6   │
        └─────┴─────┘
        """
        if not isinstance(item, slice):
            msg = (
                "LazyFrame is not subscriptable (aside from slicing)"
                "\n\nUse `select()` or `filter()` instead."
            )
            raise TypeError(msg)
        return LazyPolarsSlice(self).apply(item)

    def __str__(self) -> str:
        return f"""\
naive plan: (run LazyFrame.explain(optimized=True) to see the optimized plan)

{self.explain(optimized=False)}\
"""

    def __repr__(self) -> str:
        # don't expose internal/private classpath
        return f"<{self.__class__.__name__} at 0x{id(self):X}>"

    def _repr_html_(self) -> str:
        try:
            dot = self._ldf.to_dot(optimized=False)
            svg = subprocess.check_output(
                ["dot", "-Nshape=box", "-Tsvg"], input=f"{dot}".encode()

View on GitHub (pinned to df599052da)

Solutions

  1. Replace lf['a'] with lf.select('a') (optionally .collect() afterwards)
  2. Replace row filtering lf[lf['a'] > 1] with lf.filter(pl.col('a') > 1)
  3. Replace multi-column access lf[['a','b']] with lf.select(['a','b'])
  4. Keep slicing: lf[2:10] is valid and maps to LazyFrame.slice()
  5. If DataFrame semantics are intended, call lf.collect() first and index the resulting DataFrame

Example fix

# before
val = lf['a']

# after
val = lf.select('a').collect()['a']
Defensive patterns

Strategy: type-guard

Validate before calling

from polars import LazyFrame
if isinstance(frame, LazyFrame):
    out = frame.select('a')
else:
    out = frame['a']

Type guard

def is_lazy_frame(df) -> bool:
    from polars import LazyFrame
    return isinstance(df, LazyFrame)

Prevention

When it happens

Trigger: Calling lf['colname'], lf[0], lf[['a','b']], or lf[lf['a'] > 1] on a LazyFrame instead of a DataFrame. Common when code written for pl.DataFrame is reused on pl.scan_csv()/pl.LazyFrame output, or when a function receives a DataFrame in tests but a LazyFrame in production.

Common situations: Porting DataFrame code to lazy evaluation; generic helper functions that accept either frame type; interactive exploration where users expect pandas-like __getitem__ semantics.

Related errors


AI-assisted analysis of pola-rs/polars@df599052da (2026-08-16). Data as JSON: /api/errors/028e90d1d2abe487. Report an issue: GitHub.