20
hitko
2y

Hey Python, why in the ever loving readability universe I can't break the following command across multiple lines?

df.replace(...).apply(...).reset_index().drop(...)

Oh, but I hear you say "Hitko, why you can break it into multiple lines if you break within brackets!"

To which I ask you, does this shit look any more readable?

df.replace(...
).apply(...
).reset_index(
).drop(...)

Comments
  • 7
    Add slashes.

    df.replace(...) \
    .apply(...) \
    ...
  • 4
    @IntrusionCM True, it would also work if I put the whole thing in brackets, which Python style guide says is preferred over explicit line breaks using backslash.

    Nevertheless, while it is possible to break code in a relatively clean way in Python, it requires some extra syntax which goes completely against Python philosophy of code readability and simplicity.
  • 3
    Are you sure that the object is immutable?
    only a very few python libs use the builder format.
  • 1
    @hitko In my opinion it's the opposite.

    Most languages are pretty imprecise - when code "stops" and "starts" "somewhere" it's worse.

    Python has its own delimiter, which is imho better than relying on newline interpretation which is OS independent.

    :)
  • 7
    @IntrusionCM I'm pretty sure all other languages have a simple check: if next non-whitespace character is an operator, it belongs to the current command, otherwise it's a new command.

    Python has way more complex logic: if the next non-whitespace character (except new line) is an operator, it belongs to the current command, otherwise check if there was a line break operator, and if it was, it still belongs to the same command, otherwise it's a new command. Except if the previous command is a string literal, then the operator isn't even necessary if the next command is also a string literal and the whitespace doesn't contain new line. And in that case you won't even realise the mistake since a standalone string literal is also a valid command... You get the point.
  • 1
    @stop Um yes, most Pandas methods return a new instance of DataFrame instead of modifying the object, so you can't do something like

    df.replace(...)
    df.apply(...)
    ...
  • 2
    That just looks ugly with the whole choo-choo train of commands. I'd suggest you use a middle object that goes through this train.

    If not, you could prolly also do

    df.goWild(
    ...
    ).apply(
    ...
    ).do(
    ...
    ).reset(
    ...
    ). letItGoElsa(
    ...)
  • 0
    @hitko oh, also those commands usually have a flag like `in-place` or something you could set.

    P.S. Regarding the comment above ^
  • 4
    sorry to break it to you, but python failed at readability the second it decided its nesting character is going to be invisible.
  • 1
    @NoMad In place is either marked as deprecated or removed completely in recent pandas versions, if that's what you're talking about.
  • 0
    @hitko yup. Didn't know that. No idea why they'd do such a thing tbh.
  • 2
    @NoMad as an workaround i wpuld propose:
    ...
    df = df.apply()
    df = df.to()
    df = df.kill()
  • 0
    I had the same frustation with sql queries. Then i started using this notation and it looks much more readable now

    hitko = (
    hitko
    .fuck(...)
    .marry(...)
    .kill(...)
    )
  • 0
    Real programming languages separates commands with a semicolon and nests with braces.
  • 0
    Just give me some arrow based syntax to do this very thing and I'll be happy.

    df.replace() => apply() => reset_index() => drop()
Add Comment