-1

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.

Bharel
  • 23,672
  • 5
  • 40
  • 80
Paweł Pedryc
  • 368
  • 2
  • 5
  • 19
  • There's plenty of solutions in there including using `*args`. – Bharel May 22 '22 at 13:51
  • Have you looked at the answers? – Bharel May 22 '22 at 13:54
  • 1
    Yes, you were right, there is a solution with factors I needed(first post). I would like to know - anyway - why I got an error output. What's wrong with `**kwargs`? – Paweł Pedryc May 22 '22 at 14:03
  • How to fish is more important than [the](https://stackoverflow.com/questions/1769403/what-is-the-purpose-and-use-of-kwargs) [fish](https://stackoverflow.com/questions/36901/what-does-double-star-asterisk-and-star-asterisk-do-for-parameters) :-) Searching well will help you a lot big time, otherwise you'll be waiting for other people to answer which will take you considerably longer each time. – Bharel May 22 '22 at 14:15
  • I'm looking for a solution related to my question: with `**kwargs`. I haven't seen any similar case on the web ( for python 3.x). Just with `**kwargs`. – Paweł Pedryc May 22 '22 at 14:24

1 Answers1

1

**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.

Bharel
  • 23,672
  • 5
  • 40
  • 80
  • 1
    Thank you, now I understand why I could find a good solution with `**kwargs`. I was looking at it from the wrong angle. – Paweł Pedryc May 22 '22 at 14:58