0

I have a function that has two arguments that are both lists as shown below

def myfunc(arg1, arg2):
    return arg1*arg2

arg1 = [1,2,3,4]
arg2 = [10,9,8]

I want to return a list of each possible PERMUTATION of the two arguments.

So the result should be something like:

[10,9,8,20,18,16.......]

I believe this isn't possible with maps and zip as they would return something like:

[10,18,24]

Is there any easy way to get this done without having to write out the arguments manually?

P.s: I'm using a placeholder function in my example, so i definitely need a way to pass the two lists as arguments

Moinuddin Quadri
  • 46,825
  • 13
  • 96
  • 126
Saad Shahid
  • 73
  • 2
  • 9

3 Answers3

1

Since you want to pass multiple lists to you function dynamically, you can write custom function using *args (Read Use of *args and **kwargs to know more).

Within your function you can use combination of itertools.product(), operator.mul() and functools.reduce() (or reduce() in Python 2.x) within a list comprehension expression to get the cartesian product of your lists as:

from itertools import product
from operator import mul

# In Python 3+
# from functools import reduce

def list_multiplication(*args):
     return [reduce(mul, a) for a in product(*args)]

Sample Run:

# with 2 lists as argument
>>> list_multiplication([1,2,3,4], [10,9,8])
[10, 9, 8, 20, 18, 16, 30, 27, 24, 40, 36, 32]

# with 3 lists as argument
>>> list_multiplication([1,2,3,4], [10,9,8], [7, 8, 9])
[70, 80, 90, 63, 72, 81, 56, 64, 72, 140, 160, 180, 126, 144, 162, 112, 128, 144, 210, 240, 270, 189, 216, 243, 168, 192, 216, 280, 320, 360, 252, 288, 324, 224, 256, 288]
Moinuddin Quadri
  • 46,825
  • 13
  • 96
  • 126
  • Right, just commented above, the function Im using is actually a lot more complicated than the product function I wrote above. So I would still need a way to pass arguments from two lists that handle each permutation right? I don't believe the options above would be able to do that – Saad Shahid Jan 18 '21 at 00:32
  • Do you mean that your `list` arguments which you need to pass needs to be dynamic? for example, you want your function call with 2, 3, 4, etc arguments? – Moinuddin Quadri Jan 18 '21 at 00:44
1

Try something which is called list comprehension, very useful thing in python!

 x=[i*j for i in arg1 for j in arg2]
Michał89
  • 87
  • 8
1

You can always use NumPy (numpy.outer):

import numpy as np

arg1 = [1,2,3,4]
arg2 = [10,9,8]

np.outer(arg1, arg2).flatten()
#array([10,  9,  8, 20, 18, 16, 30, 27, 24, 40, 36, 32])

The method numpy.ndarray.flatten is for getting a 1-dimensional output, if you don't use it you'll get a matrix:

#np.outer(arg1, arg2)
#array([[10,  9,  8],
#       [20, 18, 16],
#       [30, 27, 24],
#       [40, 36, 32]])
Pablo C
  • 4,661
  • 2
  • 8
  • 24
  • Apologies, the function Im using is a lot more complicated than the product, I just used that to make the question easier to understand, so I essentially need a a way to pass lists as arguments into a function that is fairly complicated. Is there anyway to achieve that? – Saad Shahid Jan 18 '21 at 00:30
  • @SaadShahid can you be more specific? – Pablo C Jan 18 '21 at 00:38