75

Given multiple list of possibly varying length, I want to iterate over all combinations of values, one item from each list. For example:

first = [1, 5, 8]
second = [0.5, 4]

Then I want the output of to be:

combined = [(1, 0.5), (1, 4), (5, 0.5), (5, 4), (8, 0.5), (8, 4)]

I want to iterate over the combined list. How do I get this done?

Karl Knechtel
  • 62,466
  • 11
  • 102
  • 153
DurgaDatta
  • 3,952
  • 4
  • 27
  • 34

2 Answers2

132

itertools.product should do the trick.

>>> import itertools
>>> list(itertools.product([1, 5, 8], [0.5, 4]))
[(1, 0.5), (1, 4), (5, 0.5), (5, 4), (8, 0.5), (8, 4)]

Note that itertools.product returns an iterator, so you don't need to convert it into a list if you are only going to iterate over it once.

eg.

for x in itertools.product([1, 5, 8], [0.5, 4]):
    # do stuff
Jinhua Wang
  • 1,679
  • 1
  • 17
  • 44
Volatility
  • 31,232
  • 10
  • 80
  • 89
  • What about if `second = [0.5, 4, 1]` and we consider the output `(1, 4)` is same as output `(4, 1)`? – Nate Anderson Oct 28 '15 at 17:07
  • 1
    @TheRedPea (Assuming you have a `4` in the first list, and you want only unique outputs in the result) I think you will just have to filter afterwards, using `set(tuple(sorted(lst)) for lst in itertools.product(...))` or something like that. – Volatility Oct 29 '15 at 07:32
  • @Volatility , would it be also possible to add these combinations: `(0.5, 1), (0.5, 5), (0.5, 8), (4, 1), (4, 5), (4, 8)`? – Reman Feb 16 '16 at 17:57
  • The problem with this solution is that it does not work if we give the product method the list of lists. We should only give it the separated lists and only in that case it can return the product. Correct me if I am wrong. – Pedram May 14 '17 at 20:41
  • @Pedram that's correct. If you have just the list of lists then you would need to unpack it into separate arguments using `*` (see [this](http://stackoverflow.com/questions/36901/what-does-double-star-and-star-do-for-parameters)). – Volatility May 15 '17 at 04:27
28

This can be achieved without any imports using a list comprehension. Using your example:

first = [1, 5, 8]
second = [0.5, 4]

combined = [(f,s) for f in first for s in second]

print(combined)
# [(1, 0.5), (1, 4), (5, 0.5), (5, 4), (8, 0.5), (8, 4)]
SpinUp __ A Davis
  • 5,016
  • 1
  • 30
  • 25
  • This should be top answer, for current Python. I might be wrong, but I think the original top answer was for Python 2 - maybe list comp like this answer were not possible then. – msm1089 Sep 27 '20 at 16:59
  • 2
    I disagree with @msm1089, the solution with list comprehensions is only practical for a known, small number of original lists. On the contrary, the `itertools` approach can cover any number of lists, e.g. `itertools.product(*my_lists)`. This is more generic and sometimes necessary. – Cedric Druck Oct 06 '20 at 13:54
  • Actually, I agree with you @CedricDruck. Most general is the itertools approach. But if, as you say, there are only a small number of small lists, list comp is probably better. – msm1089 Oct 08 '20 at 08:56
  • Good point, @CedricDruck, both methods have their place. I think most people would like to avoid yet another import when they can, though. The specific question asked here by the OP was a small number of known lists, so the answer very much applies. – SpinUp __ A Davis Oct 09 '20 at 15:23