pandas .apply args unpacks lists automatically?

Viewed 38

I can't find anything on this in the documentation or on SO yet…

Given:

def applied_func(row, list_of_values):
  for val in list_of_values:
    // do something generative
  return generated_thing

list_for_applied_func = ['foo', 'bar', 'baz']

df['computed value'] = df.apply(applied_func, args=(list_for_applied_func), axis=1))

I get the unexpected error "applied_func() takes 2 positional arguments but 4 were given. This tells me that it is auto-unpacking list_of_applied_func in the above. How is one to treat the list passed as an argument as a list for use in the computed function?

2 Answers

Indeed, as this line shows, the args is sent with unpacking i.e. f(..., *args). A remedy is to turn your list into a 1-tuple:

                                  # note the comma|
df.apply(applied_func, args=(list_for_applied_func,), axis=1))

This way args will be a 1-tuple and when *'ed, a list will be passed.

When you do (list_for_applied_func), you are simply passing list_for_applied_func, you need to actually pass a tuple that contains a list, so you can try:

df['computed value'] = df.apply(applied_func, args=(list_for_applied_func,), axis=1))

For example, try this

>>> isinstance(([3, 4, 5]), tuple)
False
>>> isinstance(([3, 4, 5], ), tuple)
True
Related