Closed DeviousStoat closed 7 months ago
Makes sense to me! I'm all in favor.
Are there any other places where a type change like this would also make sense/make things easier?
Not really type changes but improvement ideas I had:
There is the sort_by
min_by
max_by
functions that don't support accessing the key of a mapping in the iteratee. i think it would be cool if we could. I had this use case recently and I had to go out of the chain to use builtins min
, max
instead.
Also one thing that would be cool to have in the library is a maybe apply function kinda thing. pydash.get
is really cool but I am a bit sad that it is not typable in the current python type system. One very common use case of it I believe is to get data from an optional value:
import pydash as _
class SomeClass:
attribute: int = 5
@classmethod
def build(cls) -> "SomeClass | None":
...
some_class = SomeClass.build()
attr = _.get(some_class, "attribute") # `attr` is `Any`, we cannot type `get` properly
But we could have a maybe_apply
function thing that would take a callable:
attr = _.maybe_apply(some_class, lambda x: x.attribute) # `attr` is `int | None`
this is typable.
And it is not restricted to attribute or key getting, we can just apply anything to an optional value, it abstracts this pattern:
def add1(x: int) -> int:
return x + 1
some_int: Optional[int]
if some_int is not None:
some_int = add1(some_int)
# instead just do
some_int = _.maybe_apply(some_int, add1)
And with the chaining interface I think it would look really cool, eg:
import pydash as _
from dataclasses import dataclass
@dataclass
class SomeAddress:
city: str | None
@dataclass
class SomeUser:
addr: SomeAddress | None
@dataclass
class SomeClass:
user: SomeUser | None
some_class: SomeClass
maybe_upper_city: str | None = (
_.chain(some_class)
.maybe_apply(lambda x: x.user)
.maybe_apply(lambda x: x.addr)
.maybe_apply(lambda x: x.city)
.maybe_apply(lambda x: x.upper())
)
Would you be open to PR that switches
zip_
,zip_with
andto_pairs
to return list of tuples instead?Using a list in python is very similar to using a tuple but in static typing having lists is a bit annoying. For example:
This doesn't make much sense, we know
first_key
should bestr
andfirst_value
should beint
. Ifto_pairs
returned list of tuples instead we could type it better and not have this problem.Same with
zip_
:zipped
is a list of lists ofstr | int
, we lost the order on the type level, int and str are blend in the lists.And I think the hardest to work with might be
zip_with
while this is valid at runtime, the type checker doesn't know that the first argument is
str
and second isint
because it is all blend into thelist[str | int]
This makes them really hard to use in a type checked context. Chaining functions with the result of these functions is very impractical. I think it would make a lot more sense for these functions to return tuples.