I have made a function to drop a row in a pandas.DataFrame. Since, in general, the input dataframe of a function is just a reference to the dataframe. So any change made in that function to the dataframe will be preserved outside that function. Therefore, there are two choices when designing the function:

  1. simply make the change without returning the dataframe.
  2. or, make the change and return the dataframe.

See my code below (function change_df_1 and change_df_2). Could you please let me know which one is better or do you prefer? My concern is readability/clarity of the code.

import pandas as pd

def get_df():
    df = pd.DataFrame({'A': [10, 20, 30], 'B':[100, 200, 300]})
    return df

def change_df_1(df: pd.DataFrame):
    df.drop(index=[1], inplace=True)

def change_df_2(df: pd.DataFrame) -> pd.DataFrame:
    df.drop(index=[1], inplace=True)
    return df

def main():
    df = get_df()
    print(f'Original {df=}')

    print(f'Changed_with 1: {df=}')

    # change_df_2(df=df)
    # print(f'Changed_with 2: {df=}')

if __name__ == '__main__':

The documentation for sort, to pick a common example, says:

You can also use the list.sort() method. It modifies the list in-place (and returns None to avoid confusion).

One benefit of returning the object is to chain calls. If consumers of your code expect to be able to chain calls, perhaps returning the object makes sense. Otherwise I would say the more common behavior in Python is to return None from functions that mutate their arguments.

(Other languages may have other conventions.)

  • \$\begingroup\$ pandas follows this convention and when you have inplace=True it returns None. I believe you call an interface that allows you to chain a fluent interface. \$\endgroup\$ – AChampion Sep 12 '20 at 9:25

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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