Reputation: 722
suppose to have a generic function:
def fn(*args, **kwargs):
return {"args":args,"kwargs":kwargs}
the star operator in the signature allows the user to call the function with any arbitrary number of arguments by using one star to "unravel" tuples and two for dicts.
now suppose we want to call this function multiple times with some of those args and kwargs staying the same, and some other varying between each call.
One way to accomplish this result would be:
result = [fn(*dargs, *args, **dkwargs, **kwargs) for dargs in dynamic_args for dkwargs in dynamic_kwargs]
where dynamic_args could be any kind of iterable (including generators)
example:
dynamic_args = [(1, 2, 3), (4, 6, 7), (8, 9, 0)]
dynamic_kwargs = [{"a": "A"}, {"b": "B"}, {"c": "C"}]
args = ("these", "are", "static", "args", )
kwargs = {"static": "kwarg"}
result:
{'args': (1, 2, 3, 'these', 'are', 'static', 'args'), 'kwargs': {'a': 'A', 'static': 'kwarg'}}
{'args': (1, 2, 3, 'these', 'are', 'static', 'args'), 'kwargs': {'b': 'B', 'static': 'kwarg'}}
{'args': (1, 2, 3, 'these', 'are', 'static', 'args'), 'kwargs': {'c': 'C', 'static': 'kwarg'}}
{'args': (4, 5, 6, 'these', 'are', 'static', 'args'), 'kwargs': {'a': 'A', 'static': 'kwarg'}}
{'args': (4, 5, 6, 'these', 'are', 'static', 'args'), 'kwargs': {'b': 'B', 'static': 'kwarg'}}
{'args': (4, 5, 6, 'these', 'are', 'static', 'args'), 'kwargs': {'c': 'C', 'static': 'kwarg'}}
{'args': (7, 8, 9, 'these', 'are', 'static', 'args'), 'kwargs': {'a': 'A', 'static': 'kwarg'}}
{'args': (7, 9, 0, 'these', 'are', 'static', 'args'), 'kwargs': {'b': 'B', 'static': 'kwarg'}}
{'args': (8, 9, 0, 'these', 'are', 'static', 'args'), 'kwargs': {'c': 'C', 'static': 'kwarg'}}
i think that this works because when the calling function gets the input, *(kw)args is considered as a continuation of d(kw)args, as a single entity (tuple,dict).
Problem is... my linter (flake8) sees it as an InvalidSintax error, am i following the hacky non-pythonic path once again ?
and if so, is there another way to obtain the same result without adding logic to the code of the function and possibly retaining the list comprehension syntax?
Upvotes: 0
Views: 548
Reputation: 532268
You have flake8
installed for Python 2 only, so it is analyzing your code according to Python 2's rules. See http://flake8.pycqa.org/en/latest/user/invocation.html for using flake8
to use different versions of Python you may have installed.
However, you can write your code in such a way that it will run identically under both Python 2 and Python 3.
from itertools import chain
result = [fn(*chain(args, dargs),
**dict(chain(kwargs.items(), dkwargs.items())))
for dargs in dynamic_args
for dkwargs in dynamic_kwargs]
Upvotes: 1