1
\$\begingroup\$

I've got something really simple this time where I'm mapping pandas' Series to dataclasses with a oneliner helper function (as I have several models):

import pandas as pd
from typing import Any
from dataclasses import dataclass, fields

def create_dataclass(data: pd.Series, factory: Any) -> Any:
    return factory(**{f.name: data[f.name] for f in fields(factory)})

I call it like this:

@dataclass
class Person:
    first_name: str
    last_name: str

@dataclass
class Employee(Person):
    company: str

def create_employees(data: pd.DataFrame) -> List[Employee]:
    return [create_dataclass(r, Employee) for i, r in data.iterrows()]

Do you think it still could be more pythonic?

\$\endgroup\$

1 Answer 1

1
\$\begingroup\$

Looks very pythonic to me.

Thumbs up, LGTM, ship it!


Ok, fine, I have a few minor remarks.

Maybe the Any annotations could be finessed a bit to be more informative? Or maybe just drop the -> Any:.


    return factory(**{f.name: data[f.name]  for f in fields(factory)})

The ** double star is as pythonic as it gets. But notice that what we really care about is name. So perhaps

from operator import attrgetter

    ...
    return factory(**{name: data[name] for name in map(attrgetter('name'), fields(factory))})

Hmmm, not sure that longer works out to a win. Prolly better to keep the code as-is.


    ... for _, r in data.iterrows()]

nit: Prefer row over r. Whatever.

Like I said, ship it.

\$\endgroup\$

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.