You can define the function as -
def foo(**kwargs):
print(kwargs)
This will allow named parameters to be passed in, and kwargs would be a dictionary of those named parameters -
>>> foo(categories=["oll","Academic Data"], names=["mary","jack"])
{'categories': ['oll', 'Academic Data'], 'names': ['mary', 'jack']}
>>> foo(names=["mary","jack"], categories=["oll","Academic Data"])
{'categories': ['oll', 'Academic Data'], 'names': ['mary', 'jack']}
>>> foo(names=["mary","jack"])
Or another option (if you want to be explicit about the parameters) is to set a default value for the parameters, when using named arguments, they can be in any order, exmaple -
>>> def foo1(categories=None,names=None):
... print('categories - ' + str(categories))
... print('names - ' + str(names))
...
>>> foo1(categories=["oll","Academic Data"], names=["mary","jack"])
categories - ['oll', 'Academic Data']
names - ['mary', 'jack']
>>> foo1(names=["mary","jack"], categories=["oll","Academic Data"])
categories - ['oll', 'Academic Data']
names - ['mary', 'jack']
>>> foo1(names=["mary","jack"])
categories - []
names - ['mary', 'jack']
Even without default values, when you are using named arguments in function calling, the order of the arguments do not matter, they only matter when you do not specify the names of the arguments when calling the function). Example -
>>> def func(a, b):
... print(a, b)
...
>>> func(b=1,a=2)
2 1
>>> func(a=2,b=1)
2 1
Adding default value for the argument, makes them optional during calling.