2

I'd like to generate a large list of lists to pass to a function. Part of this is passing keyword arguments, but I can't seem to get it to work, as the keyword dict gets scooped up as a positional argument:

mylist = [
['cheese', 'toast', 'bread', {exempt=True}],
['bagel', 'apple', 'oatmeal', {exempt=True}],
]

for i in mylist:
    myfunc(*i)

def myfunc(first, *args, exempt=False, **kwargs):
   if exempt:
        return

Hopefully this gets the idea across. Is this sort of implementation possible?

  • 1
    you should use a sequence for positional arguments, e.g. `args = (1,2,3)`, and then a `dict` for keyword arguments, `kwargs = {"foo":42, "bar":"baz"}` then use `myfunc(*args, **kwargs)`. So maybe a list of args, kwargs pairs – juanpa.arrivillaga Oct 10 '22 at 22:48
  • The data needs to be structured in a way that makes it possible to tell, which are the positional and which are the keyword arguments. After all, a `dict` is a perfectly valid positional argument. That's a *design* question; once there is a concrete task, the remaining question is "how do I pass the dict as keyword arguments?", for which I have linked a duplicate. – Karl Knechtel Oct 10 '22 at 23:01

1 Answers1

3

I'd suggest having a list of args, kwargs pairs, like this:

mylist = [
    (['cheese', 'toast', 'bread'], {'exempt': True}),
    (['bagel', 'apple', 'oatmeal'], {'exempt': True}),
]

def myfunc(first, *args, exempt=False, **kwargs):
   if exempt:
        return

for args, kwargs in mylist:
    myfunc(*args, **kwargs)

If you're stuck with mylist in its original format, you could do this to neatly assign the last element to kwargs and the remainder to args:

for *args, kwargs in mylist:
    myfunc(*args, **kwargs)

but you need to be very certain then that the last element is always the kwargs dict (or add code to check that it is and substitute an empty dict if it's not).

Samwise
  • 68,105
  • 3
  • 30
  • 44