Skip to content

Commit

Permalink
feat: add Series.__iter__ (#1057)
Browse files Browse the repository at this point in the history
  • Loading branch information
FBruzzesi authored Sep 24, 2024
1 parent 0e26ef6 commit b4c31b3
Show file tree
Hide file tree
Showing 7 changed files with 32 additions and 6 deletions.
1 change: 1 addition & 0 deletions docs/api-reference/series.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
members:
- __arrow_c_stream__
- __getitem__
- __iter__
- abs
- alias
- all
Expand Down
4 changes: 4 additions & 0 deletions narwhals/_arrow/series.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
from typing import TYPE_CHECKING
from typing import Any
from typing import Iterable
from typing import Iterator
from typing import Literal
from typing import Sequence
from typing import overload
Expand Down Expand Up @@ -702,6 +703,9 @@ def mode(self: Self) -> ArrowSeries:
plx.col(col_token) == plx.col(col_token).max()
)[self.name]

def __iter__(self: Self) -> Iterator[Any]:
yield from self._native_series.__iter__()

@property
def shape(self) -> tuple[int]:
return (len(self._native_series),)
Expand Down
8 changes: 2 additions & 6 deletions narwhals/_expression_parsing.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
from typing import overload

from narwhals.dependencies import is_numpy_array
from narwhals.utils import flatten

if TYPE_CHECKING:
from narwhals._arrow.dataframe import ArrowDataFrame
Expand Down Expand Up @@ -95,7 +94,7 @@ def evaluate_into_exprs(
"""Evaluate each expr into Series."""
series: ListOfCompliantSeries = [ # type: ignore[assignment]
item
for sublist in (evaluate_into_expr(df, into_expr) for into_expr in flatten(exprs))
for sublist in (evaluate_into_expr(df, into_expr) for into_expr in exprs)
for item in sublist
]
for name, expr in named_exprs.items():
Expand Down Expand Up @@ -157,9 +156,7 @@ def parse_into_exprs(
) -> ListOfCompliantExpr:
"""Parse each input as an expression (if it's not already one). See `parse_into_expr` for
more details."""
return [
parse_into_expr(into_expr, namespace=namespace) for into_expr in flatten(exprs)
] + [
return [parse_into_expr(into_expr, namespace=namespace) for into_expr in exprs] + [
parse_into_expr(expr, namespace=namespace).alias(name)
for name, expr in named_exprs.items()
]
Expand All @@ -181,7 +178,6 @@ def parse_into_expr(
- if it's a string, then convert it to an expression
- else, raise
"""

if hasattr(into_expr, "__narwhals_expr__"):
return into_expr # type: ignore[return-value]
if hasattr(into_expr, "__narwhals_series__"):
Expand Down
4 changes: 4 additions & 0 deletions narwhals/_pandas_like/series.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
from typing import TYPE_CHECKING
from typing import Any
from typing import Iterable
from typing import Iterator
from typing import Literal
from typing import Sequence
from typing import overload
Expand Down Expand Up @@ -665,6 +666,9 @@ def mode(self: Self) -> Self:
result.name = native_series.name
return self._from_native_series(result)

def __iter__(self: Self) -> Iterator[Any]:
yield from self._native_series.__iter__()

@property
def str(self) -> PandasLikeSeriesStringNamespace:
return PandasLikeSeriesStringNamespace(self)
Expand Down
4 changes: 4 additions & 0 deletions narwhals/series.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
from typing import TYPE_CHECKING
from typing import Any
from typing import Callable
from typing import Iterator
from typing import Literal
from typing import Sequence
from typing import overload
Expand Down Expand Up @@ -2407,6 +2408,9 @@ def mode(self: Self) -> Self:
"""
return self._from_compliant_series(self._compliant_series.mode())

def __iter__(self: Self) -> Iterator[Any]:
yield from self._compliant_series.__iter__()

@property
def str(self) -> SeriesStringNamespace:
return SeriesStringNamespace(self)
Expand Down
16 changes: 16 additions & 0 deletions tests/series_only/__iter___test.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
from __future__ import annotations

from collections.abc import Iterable
from typing import Any

import narwhals.stable.v1 as nw
from tests.utils import compare_dicts

data = [1, 2, 3]


def test_to_list(constructor_eager: Any) -> None:
s = nw.from_native(constructor_eager({"a": data}), eager_only=True)["a"]

assert isinstance(s, Iterable)
compare_dicts({"a": [x for x in s]}, {"a": [1, 2, 3]}) # noqa: C416
1 change: 1 addition & 0 deletions utils/check_api_reference.py
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
"item",
"scatter",
"to_native",
"__iter__",
}
BASE_DTYPES = {"NumericType", "DType", "TemporalType"}

Expand Down

0 comments on commit b4c31b3

Please sign in to comment.