I'm trying to recreate itertools.product
.
I know how to create a loop for this task, ex.:
arr1 = [1, 2, 3]
arr2 = [5, 6, 7]
arr_out = []
for i in arr1:
for i1 in arr2:
final = i, i1
arr_out.append(final)
print(arr_out)
output:
[(1, 5), (1, 6), (1, 7), (2, 5), (2, 6), (2, 7), (3, 5), (3, 6), (3, 7)]
But I wonder how to create a function from that with kwargs
.
I try something like this:
arr1 = [1, 2, 3]
arr2 = [5, 6, 7]
def my_cool_product(**kwargs):
arr_out = []
for i in kwargs[0].items():
for i1 in kwargs[1].items():
final = i, i1
arr_out.append(final)
print(my_cool_product(arr1, arr2))
But it doesn't work.
output:
TypeError: my_cool_product() takes 0 positional arguments but 2 were given
I don't know how to call each subsequent kwarg
in a nested loop.
I want to get the same output as in the first example.
The goal is to do it without importing any modules, like itertools
, in other words, do it from scratch.
**kwargs
is unfit for a function like the one you're proposing.
As linked from in the comments, **kwargs
is used for variadic keyword argument functions. In your case you're looking for any number of unnamed lists.
Let's say there's only 2 arrays you're trying to get the product of, as you imply in your example function:
def my_cool_product(**kwargs):
arr_out = []
for i in kwargs["array1"]:
for i1 in kwargs["array2"]:
final = i, i1
arr_out.append(final)
return arr_out
You may then use it like so:
>>> my_cool_product(array1=[1,2,3], array2=[4,5,6])
[(1, 4), (1, 5), (1, 6), (2, 4), (2, 5), (2, 6), (3, 4), (3, 5), (3, 6)]
But since the names array1
and array2
are meaningless, using *args
would be preferred:
def my_cool_product(*args):
arr_out = []
for i in args[0]:
for i1 in args[1]:
final = i, i1
arr_out.append(final)
return arr_out
>>> my_cool_product([1,2,3], [4,5,6])
[(1, 4), (1, 5), (1, 6), (2, 4), (2, 5), (2, 6), (3, 4), (3, 5), (3, 6)]
For further supporting any number of lists, please see the duplicate questions, so as for the difference between *args
and **kwargs
.