0

I have this function:

def print_excel(path, filename, **kwargs):
    with pd.ExcelWriter(path + filename + timestr1 + '.xlsx') as writer:
        for df, sheet_name in kwargs.items():
            df.to_excel(writer, sheet_name=sheet_name, index=False)

And I also have this function call:

keywords = {df1: 'Sheet1', df2:'Sheet2'}
print_excel(path1, '_FileName.xlsx', **keywords)

However, when calling the function, it gives this error:

TypeError: 'DataFrame' objects are mutable, thus they cannot be hashed

Why is this happening and how can I solve it?

banana_99
  • 591
  • 5
  • 15

1 Answers1

2

By default, most immutable python objects are hashable, while most mutable objects are not. An object has to be hashable for it to be used as a dictionary key — you can read more about what that means and why that's the case here: What does "hashable" mean in Python?.

However, an object does not need to be hashable to be a dictionary value, so, in your case, a simple solution is just to swap the keys and values in your dictionary:

import pandas as pd

def print_excel(path, filename, sheet_dict):
    with pd.ExcelWriter(path + filename + timestr1 + '.xlsx') as writer:
        for sheet_name, df in sheet_dict.items():
            df.to_excel(writer, sheet_name=sheet_name, index=False)

sheets = {'Sheet1': df1, 'Sheet2': df2}
print_excel(path1, '_FileName.xlsx', sheets)

I took out the dictionary unpacking (the ** notation) in your function signature, by the way, as it's entirely unnecessary for your function. In your case, the dictionary is just an input to your function. There's a related stack overflow question here on when to use ** notation in function definitions, and a great tutorial here on some of the really cool things you can do with tuple and dictionary unpacking in python.

Alex Waygood
  • 6,304
  • 3
  • 24
  • 46