0

I am trying to write a function that will be used on multiple dictionaries of dataframes. My hope is to perform multiple assignments and do it all in one line. for example:

x, y, z = function(x, y, z)

However, with the function, I can't return multiple values for the multiple assignments. This is what I currently have

def split_pre(*args):
    for arg in args:
        newdict = {}
        for key, sheet in arg.items():
            if isinstance(sheet, str):
                continue
            else:
                newdict[key] = sheet[sheet.Year < 2000]
        return newdict

My thinking is that for each arg it would return the dictionary I created, but I get:

ValueError: too many values to unpack (expected 2)

The inputs to this function would be a dictionary made up of dataframes, e.g.,

x = {1:df, 2:df, 3:df...}

and the desired output would be of the same structure, but with the altered dfs from the function

I'm still quite new to python and this isn't super important, but I was wondering if anyone knew of a succinct way to get at this.

  • Please, provide an example of an input and desired output – Kolay.Ne Mar 31 '21 at 17:46
  • - The function returns when the first `return` is hit, so only the dict for the first `arg` is going to be created. - Python does not support object/dict destructuring (yet) – DeepSpace Mar 31 '21 at 17:50
  • @DeepSpace although, iterable unpacking *works* with `dict` objects, since dict objects are iterable, only you'll just get the keys. – juanpa.arrivillaga Mar 31 '21 at 18:56

1 Answers1

1

Do you want to return a dictionary per arg?

As already stated by @DeepSpace, Python stops processing the function when the first return command is executed. You can fix your problem in two ways: either create a list where you collect the dictionaries you want to return, or create a generator function:

# Solution with a list
def split_pre(*args):
    ans = []
    for arg in args:
        newdict = {}
        for key, sheet in arg.items():
            if isinstance(sheet, str):
                continue
            else:
                newdict[key] = sheet[sheet.Year < 2000]
        ans.append(newdict)
    return ans

or

# Solution with a generator
def split_pre(*args):
    for arg in args:
        newdict = {}
        for key, sheet in arg.items():
            if isinstance(sheet, str):
                continue
            else:
                newdict[key] = sheet[sheet.Year < 2000]
        yield newdict

In case you call a function in the way you do (a, b, c = func(x, y, z)) both samples are going to work in the same way. But they are not actually the same and I'd recommend using the solution with lists if you're not familiar with generators (you can read more about the yield keyword here)

Kolay.Ne
  • 1,345
  • 1
  • 8
  • 23