Get the cartesian product of a series of lists?












241















How can I get the Cartesian product (every possible combination of values) from a group of lists?



Input:



somelists = [
[1, 2, 3],
['a', 'b'],
[4, 5]
]


Desired output:



[(1, 'a', 4), (1, 'a', 5), (1, 'b', 4), (1, 'b', 5), (2, 'a', 4), (2, 'a', 5) ...]









share|improve this question




















  • 15





    be aware that 'every possible combination' is not quite the same as 'Cartesian product', since in Cartesian products, duplicates are allowed.

    – Triptych
    Feb 10 '09 at 20:08






  • 6





    Is there a non duplicate version of cartesian product?

    – KJW
    Nov 13 '13 at 5:32






  • 9





    @KJW Yes, set(cartesian product)

    – NoBugs
    Feb 12 '15 at 7:04






  • 4





    There should be no duplicates in a Cartesian product, unless the input lists contain duplicates themselves. If you want no duplicates in the Cartesian product, use set(inputlist) over all your input lists. Not on the result.

    – CamilB
    Aug 24 '17 at 8:39
















241















How can I get the Cartesian product (every possible combination of values) from a group of lists?



Input:



somelists = [
[1, 2, 3],
['a', 'b'],
[4, 5]
]


Desired output:



[(1, 'a', 4), (1, 'a', 5), (1, 'b', 4), (1, 'b', 5), (2, 'a', 4), (2, 'a', 5) ...]









share|improve this question




















  • 15





    be aware that 'every possible combination' is not quite the same as 'Cartesian product', since in Cartesian products, duplicates are allowed.

    – Triptych
    Feb 10 '09 at 20:08






  • 6





    Is there a non duplicate version of cartesian product?

    – KJW
    Nov 13 '13 at 5:32






  • 9





    @KJW Yes, set(cartesian product)

    – NoBugs
    Feb 12 '15 at 7:04






  • 4





    There should be no duplicates in a Cartesian product, unless the input lists contain duplicates themselves. If you want no duplicates in the Cartesian product, use set(inputlist) over all your input lists. Not on the result.

    – CamilB
    Aug 24 '17 at 8:39














241












241








241


51






How can I get the Cartesian product (every possible combination of values) from a group of lists?



Input:



somelists = [
[1, 2, 3],
['a', 'b'],
[4, 5]
]


Desired output:



[(1, 'a', 4), (1, 'a', 5), (1, 'b', 4), (1, 'b', 5), (2, 'a', 4), (2, 'a', 5) ...]









share|improve this question
















How can I get the Cartesian product (every possible combination of values) from a group of lists?



Input:



somelists = [
[1, 2, 3],
['a', 'b'],
[4, 5]
]


Desired output:



[(1, 'a', 4), (1, 'a', 5), (1, 'b', 4), (1, 'b', 5), (2, 'a', 4), (2, 'a', 5) ...]






python list






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Jan 19 '17 at 2:31









martineau

67.6k1089182




67.6k1089182










asked Feb 10 '09 at 19:54









ʞɔıuʞɔıu

29.5k2683125




29.5k2683125








  • 15





    be aware that 'every possible combination' is not quite the same as 'Cartesian product', since in Cartesian products, duplicates are allowed.

    – Triptych
    Feb 10 '09 at 20:08






  • 6





    Is there a non duplicate version of cartesian product?

    – KJW
    Nov 13 '13 at 5:32






  • 9





    @KJW Yes, set(cartesian product)

    – NoBugs
    Feb 12 '15 at 7:04






  • 4





    There should be no duplicates in a Cartesian product, unless the input lists contain duplicates themselves. If you want no duplicates in the Cartesian product, use set(inputlist) over all your input lists. Not on the result.

    – CamilB
    Aug 24 '17 at 8:39














  • 15





    be aware that 'every possible combination' is not quite the same as 'Cartesian product', since in Cartesian products, duplicates are allowed.

    – Triptych
    Feb 10 '09 at 20:08






  • 6





    Is there a non duplicate version of cartesian product?

    – KJW
    Nov 13 '13 at 5:32






  • 9





    @KJW Yes, set(cartesian product)

    – NoBugs
    Feb 12 '15 at 7:04






  • 4





    There should be no duplicates in a Cartesian product, unless the input lists contain duplicates themselves. If you want no duplicates in the Cartesian product, use set(inputlist) over all your input lists. Not on the result.

    – CamilB
    Aug 24 '17 at 8:39








15




15





be aware that 'every possible combination' is not quite the same as 'Cartesian product', since in Cartesian products, duplicates are allowed.

– Triptych
Feb 10 '09 at 20:08





be aware that 'every possible combination' is not quite the same as 'Cartesian product', since in Cartesian products, duplicates are allowed.

– Triptych
Feb 10 '09 at 20:08




6




6





Is there a non duplicate version of cartesian product?

– KJW
Nov 13 '13 at 5:32





Is there a non duplicate version of cartesian product?

– KJW
Nov 13 '13 at 5:32




9




9





@KJW Yes, set(cartesian product)

– NoBugs
Feb 12 '15 at 7:04





@KJW Yes, set(cartesian product)

– NoBugs
Feb 12 '15 at 7:04




4




4





There should be no duplicates in a Cartesian product, unless the input lists contain duplicates themselves. If you want no duplicates in the Cartesian product, use set(inputlist) over all your input lists. Not on the result.

– CamilB
Aug 24 '17 at 8:39





There should be no duplicates in a Cartesian product, unless the input lists contain duplicates themselves. If you want no duplicates in the Cartesian product, use set(inputlist) over all your input lists. Not on the result.

– CamilB
Aug 24 '17 at 8:39












11 Answers
11






active

oldest

votes


















291














In Python 2.6+



import itertools
for element in itertools.product(*somelists):
print(element)


Documentation:
Python 3 - itertools.product






share|improve this answer





















  • 19





    Just wanted to add the '*' character is required if you use the variable somelists as provided by the OP.

    – brian buck
    Jan 13 '11 at 22:51






  • 1





    @jaska: product() generates nitems_in_a_list ** nlists elements in the result (reduce(mul, map(len, somelists))). There is no reason to believe that yielding a single element is not O(nlists) (amortized) i.e., the time complexity is the same as for simple nested for-loops e.g., for the input in the question: nlists=3, total number of elements in the result: 3*2*2, and each element has nlists items (3 in this case).

    – jfs
    Aug 14 '15 at 22:08






  • 2





    What is the use of * before somelists? What does it do?

    – Vineet Kumar Doshi
    Aug 25 '15 at 9:04






  • 6





    @VineetKumarDoshi: Here it is used to unpcak a list into multiple arguments to the function call. Read more here: stackoverflow.com/questions/36901/…

    – Moberg
    Sep 15 '15 at 6:20






  • 3





    Note: This works only if each list contains at least one item

    – igo
    Sep 13 '17 at 12:35



















68














import itertools
>>> for i in itertools.product([1,2,3],['a','b'],[4,5]):
... print i
...
(1, 'a', 4)
(1, 'a', 5)
(1, 'b', 4)
(1, 'b', 5)
(2, 'a', 4)
(2, 'a', 5)
(2, 'b', 4)
(2, 'b', 5)
(3, 'a', 4)
(3, 'a', 5)
(3, 'b', 4)
(3, 'b', 5)
>>>





share|improve this answer































    31














    For Python 2.5 and older:



    >>> [(a, b, c) for a in [1,2,3] for b in ['a','b'] for c in [4,5]]
    [(1, 'a', 4), (1, 'a', 5), (1, 'b', 4), (1, 'b', 5), (2, 'a', 4),
    (2, 'a', 5), (2, 'b', 4), (2, 'b', 5), (3, 'a', 4), (3, 'a', 5),
    (3, 'b', 4), (3, 'b', 5)]


    Here's a recursive version of product() (just an illustration):



    def product(*args):
    if not args:
    return iter(((),)) # yield tuple()
    return (items + (item,)
    for items in product(*args[:-1]) for item in args[-1])


    Example:



    >>> list(product([1,2,3], ['a','b'], [4,5])) 
    [(1, 'a', 4), (1, 'a', 5), (1, 'b', 4), (1, 'b', 5), (2, 'a', 4),
    (2, 'a', 5), (2, 'b', 4), (2, 'b', 5), (3, 'a', 4), (3, 'a', 5),
    (3, 'b', 4), (3, 'b', 5)]
    >>> list(product([1,2,3]))
    [(1,), (2,), (3,)]
    >>> list(product())

    >>> list(product())
    [()]





    share|improve this answer


























    • The recursive version doesn't work if some of args are iterators.

      – jfs
      Feb 10 '09 at 21:43



















    17














    with itertools.product:



    import itertools
    result = list(itertools.product(*somelists))





    share|improve this answer





















    • 5





      What is the use of * before somelists?

      – Vineet Kumar Doshi
      Aug 25 '15 at 9:04











    • @VineetKumarDoshi "product(somelists)" is a cartesian product between the sublists in a way that Python first get "[1, 2, 3]" as an element and then gets other element after next comman and that is linebreak so the first product term is ([1, 2, 3],), similary for the second ([4, 5],) and so "[([1, 2, 3],), ([4, 5],), ([6, 7],)]". If you wanna get a cartesian product between elements inside the tuples, you need to tell Python with Asterisk about the tuple structure. For dictionary, you use **. More here.

      – hhh
      Feb 15 '16 at 23:13



















    11














    In Python 2.6 and above you can use 'itertools.product`. In older versions of Python you can use the following (almost -- see documentation) equivalent code from the documentation, at least as a starting point:



    def product(*args, **kwds):
    # product('ABCD', 'xy') --> Ax Ay Bx By Cx Cy Dx Dy
    # product(range(2), repeat=3) --> 000 001 010 011 100 101 110 111
    pools = map(tuple, args) * kwds.get('repeat', 1)
    result = []
    for pool in pools:
    result = [x+[y] for x in result for y in pool]
    for prod in result:
    yield tuple(prod)


    The result of both is an iterator, so if you really need a list for furthert processing, use list(result).






    share|improve this answer


























    • Per the documentation, the actual itertools.product implementation does NOT build intermediate results, which could be expensive. Using this technique could get out of hand quite quickly for moderately sized lists.

      – Triptych
      Feb 10 '09 at 20:05






    • 3





      i can only point the OP to the documentation, not read it for him.

      – user3850
      Feb 10 '09 at 20:19






    • 1





      The code from the documentation is meant to demonstrate what the product function does, not as a workaround for earlier versions of Python.

      – Triptych
      Mar 10 '09 at 21:07






    • 2





      your point being?

      – user3850
      Mar 10 '09 at 22:37



















    10














    I would use list comprehension :



    somelists = [
    [1, 2, 3],
    ['a', 'b'],
    [4, 5]
    ]

    cart_prod = [(a,b,c) for a in somelists[0] for b in somelists[1] for c in somelists[2]]





    share|improve this answer
























    • I really like this solution using list comprehensions. I don't know why isn't upvoted more, it's so simple.

      – llekn
      Nov 30 '16 at 17:38






    • 9





      @llekn because the code seems to be fixed to the number of lists

      – Bằng Rikimaru
      Jan 16 '17 at 15:33



















    9














    Here is a recursive generator, which doesn't store any temporary lists



    def product(ar_list):
    if not ar_list:
    yield ()
    else:
    for a in ar_list[0]:
    for prod in product(ar_list[1:]):
    yield (a,)+prod

    print list(product([[1,2],[3,4],[5,6]]))


    Output:



    [(1, 3, 5), (1, 3, 6), (1, 4, 5), (1, 4, 6), (2, 3, 5), (2, 3, 6), (2, 4, 5), (2, 4, 6)]





    share|improve this answer



















    • 1





      They're stored in the stack, though.

      – Quentin Pradet
      Mar 16 '15 at 11:09











    • @QuentinPradet do you mean a generator like def f(): while True: yield 1 will keep on increasing its stack size as we go through it?

      – Anurag Uniyal
      Mar 16 '15 at 22:42













    • no, but def f(): yield 1; f() will, right?

      – Quentin Pradet
      Mar 17 '15 at 10:09











    • @QuentinPradet yeah, but even in this case only the stack needed for max depth, not the whole list, so in this case stack of 3

      – Anurag Uniyal
      Mar 17 '15 at 16:14













    • It's true, sorry. A benchmark could be interesting. :)

      – Quentin Pradet
      Mar 17 '15 at 18:24



















    6














    Although there are many answers already, I would like to share some of my thoughts:



    Iterative approach



    def cartesian_iterative(pools):
    result = []
    for pool in pools:
    result = [x+[y] for x in result for y in pool]
    return result


    Recursive Approach



    def cartesian_recursive(pools):
    if len(pools) > 2:
    pools[0] = product(pools[0], pools[1])
    del pools[1]
    return cartesian_recursive(pools)
    else:
    pools[0] = product(pools[0], pools[1])
    del pools[1]
    return pools
    def product(x, y):
    return [xx + [yy] if isinstance(xx, list) else [xx] + [yy] for xx in x for yy in y]


    Lambda Approach



    def cartesian_reduct(pools):
    return reduce(lambda x,y: product(x,y) , pools)





    share|improve this answer


























    • In "Iterative Approach", why is result declared as result = [] I know that it is list_of_list but in general even if we have declare list_of_list we use and not []

      – Sachin S
      Jul 16 '17 at 15:44











    • I'm a bit of a newby in terms of Pythonic solutions. Would you or some passerby please write the list comprehension in the "iterative approach" in separate loops?

      – Johnny Boy
      Dec 10 '18 at 17:03



















    2














    Just to add a bit to what has already been said: if you use sympy, you can use symbols rather than strings which makes them mathematically useful.



    import itertools
    import sympy

    x, y = sympy.symbols('x y')

    somelist = [[x,y], [1,2,3], [4,5]]
    somelist2 = [[1,2], [1,2,3], [4,5]]

    for element in itertools.product(*somelist):
    print element


    About sympy.






    share|improve this answer

































      2














      A minor modification to the above recursive generator solution in variadic flavor:



      def product_args(*args):
      if args:
      for a in args[0]:
      for prod in product_args(*args[1:]) if args[1:] else ((),):
      yield (a,) + prod


      And of course a wrapper which makes it work exactly the same as that solution:



      def product2(ar_list):
      """
      >>> list(product(()))
      [()]
      >>> list(product2(()))

      """
      return product_args(*ar_list)


      with one trade-off: it checks if recursion should break upon each outer loop, and one gain: no yield upon empty call, e.g.product(()), which I suppose would be semantically more correct (see the doctest).



      Regarding list comprehension: the mathematical definition applies to an arbitrary number of arguments, while list comprehension could only deal with a known number of them.






      share|improve this answer

































        1














        Recursive Approach:



        def rec_cart(start, array, partial, results):
        if len(partial) == len(array):
        results.append(partial)
        return

        for element in array[start]:
        rec_cart(start+1, array, partial+[element], results)

        rec_res =
        some_lists = [[1, 2, 3], ['a', 'b'], [4, 5]]
        rec_cart(0, some_lists, , rec_res)
        print(rec_res)


        Iterative Approach:



        def itr_cart(array):
        results = []
        for i in range(len(array)):
        temp =
        for res in results:
        for element in array[i]:
        temp.append(res+[element])
        results = temp

        return results

        some_lists = [[1, 2, 3], ['a', 'b'], [4, 5]]
        itr_res = itr_cart(some_lists)
        print(itr_res)





        share|improve this answer























          Your Answer






          StackExchange.ifUsing("editor", function () {
          StackExchange.using("externalEditor", function () {
          StackExchange.using("snippets", function () {
          StackExchange.snippets.init();
          });
          });
          }, "code-snippets");

          StackExchange.ready(function() {
          var channelOptions = {
          tags: "".split(" "),
          id: "1"
          };
          initTagRenderer("".split(" "), "".split(" "), channelOptions);

          StackExchange.using("externalEditor", function() {
          // Have to fire editor after snippets, if snippets enabled
          if (StackExchange.settings.snippets.snippetsEnabled) {
          StackExchange.using("snippets", function() {
          createEditor();
          });
          }
          else {
          createEditor();
          }
          });

          function createEditor() {
          StackExchange.prepareEditor({
          heartbeatType: 'answer',
          autoActivateHeartbeat: false,
          convertImagesToLinks: true,
          noModals: true,
          showLowRepImageUploadWarning: true,
          reputationToPostImages: 10,
          bindNavPrevention: true,
          postfix: "",
          imageUploader: {
          brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
          contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
          allowUrls: true
          },
          onDemand: true,
          discardSelector: ".discard-answer"
          ,immediatelyShowMarkdownHelp:true
          });


          }
          });














          draft saved

          draft discarded


















          StackExchange.ready(
          function () {
          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f533905%2fget-the-cartesian-product-of-a-series-of-lists%23new-answer', 'question_page');
          }
          );

          Post as a guest















          Required, but never shown

























          11 Answers
          11






          active

          oldest

          votes








          11 Answers
          11






          active

          oldest

          votes









          active

          oldest

          votes






          active

          oldest

          votes









          291














          In Python 2.6+



          import itertools
          for element in itertools.product(*somelists):
          print(element)


          Documentation:
          Python 3 - itertools.product






          share|improve this answer





















          • 19





            Just wanted to add the '*' character is required if you use the variable somelists as provided by the OP.

            – brian buck
            Jan 13 '11 at 22:51






          • 1





            @jaska: product() generates nitems_in_a_list ** nlists elements in the result (reduce(mul, map(len, somelists))). There is no reason to believe that yielding a single element is not O(nlists) (amortized) i.e., the time complexity is the same as for simple nested for-loops e.g., for the input in the question: nlists=3, total number of elements in the result: 3*2*2, and each element has nlists items (3 in this case).

            – jfs
            Aug 14 '15 at 22:08






          • 2





            What is the use of * before somelists? What does it do?

            – Vineet Kumar Doshi
            Aug 25 '15 at 9:04






          • 6





            @VineetKumarDoshi: Here it is used to unpcak a list into multiple arguments to the function call. Read more here: stackoverflow.com/questions/36901/…

            – Moberg
            Sep 15 '15 at 6:20






          • 3





            Note: This works only if each list contains at least one item

            – igo
            Sep 13 '17 at 12:35
















          291














          In Python 2.6+



          import itertools
          for element in itertools.product(*somelists):
          print(element)


          Documentation:
          Python 3 - itertools.product






          share|improve this answer





















          • 19





            Just wanted to add the '*' character is required if you use the variable somelists as provided by the OP.

            – brian buck
            Jan 13 '11 at 22:51






          • 1





            @jaska: product() generates nitems_in_a_list ** nlists elements in the result (reduce(mul, map(len, somelists))). There is no reason to believe that yielding a single element is not O(nlists) (amortized) i.e., the time complexity is the same as for simple nested for-loops e.g., for the input in the question: nlists=3, total number of elements in the result: 3*2*2, and each element has nlists items (3 in this case).

            – jfs
            Aug 14 '15 at 22:08






          • 2





            What is the use of * before somelists? What does it do?

            – Vineet Kumar Doshi
            Aug 25 '15 at 9:04






          • 6





            @VineetKumarDoshi: Here it is used to unpcak a list into multiple arguments to the function call. Read more here: stackoverflow.com/questions/36901/…

            – Moberg
            Sep 15 '15 at 6:20






          • 3





            Note: This works only if each list contains at least one item

            – igo
            Sep 13 '17 at 12:35














          291












          291








          291







          In Python 2.6+



          import itertools
          for element in itertools.product(*somelists):
          print(element)


          Documentation:
          Python 3 - itertools.product






          share|improve this answer















          In Python 2.6+



          import itertools
          for element in itertools.product(*somelists):
          print(element)


          Documentation:
          Python 3 - itertools.product







          share|improve this answer














          share|improve this answer



          share|improve this answer








          edited Apr 20 '17 at 5:52









          Rufflewind

          6,65712443




          6,65712443










          answered Feb 10 '09 at 19:58









          TriptychTriptych

          155k29135165




          155k29135165








          • 19





            Just wanted to add the '*' character is required if you use the variable somelists as provided by the OP.

            – brian buck
            Jan 13 '11 at 22:51






          • 1





            @jaska: product() generates nitems_in_a_list ** nlists elements in the result (reduce(mul, map(len, somelists))). There is no reason to believe that yielding a single element is not O(nlists) (amortized) i.e., the time complexity is the same as for simple nested for-loops e.g., for the input in the question: nlists=3, total number of elements in the result: 3*2*2, and each element has nlists items (3 in this case).

            – jfs
            Aug 14 '15 at 22:08






          • 2





            What is the use of * before somelists? What does it do?

            – Vineet Kumar Doshi
            Aug 25 '15 at 9:04






          • 6





            @VineetKumarDoshi: Here it is used to unpcak a list into multiple arguments to the function call. Read more here: stackoverflow.com/questions/36901/…

            – Moberg
            Sep 15 '15 at 6:20






          • 3





            Note: This works only if each list contains at least one item

            – igo
            Sep 13 '17 at 12:35














          • 19





            Just wanted to add the '*' character is required if you use the variable somelists as provided by the OP.

            – brian buck
            Jan 13 '11 at 22:51






          • 1





            @jaska: product() generates nitems_in_a_list ** nlists elements in the result (reduce(mul, map(len, somelists))). There is no reason to believe that yielding a single element is not O(nlists) (amortized) i.e., the time complexity is the same as for simple nested for-loops e.g., for the input in the question: nlists=3, total number of elements in the result: 3*2*2, and each element has nlists items (3 in this case).

            – jfs
            Aug 14 '15 at 22:08






          • 2





            What is the use of * before somelists? What does it do?

            – Vineet Kumar Doshi
            Aug 25 '15 at 9:04






          • 6





            @VineetKumarDoshi: Here it is used to unpcak a list into multiple arguments to the function call. Read more here: stackoverflow.com/questions/36901/…

            – Moberg
            Sep 15 '15 at 6:20






          • 3





            Note: This works only if each list contains at least one item

            – igo
            Sep 13 '17 at 12:35








          19




          19





          Just wanted to add the '*' character is required if you use the variable somelists as provided by the OP.

          – brian buck
          Jan 13 '11 at 22:51





          Just wanted to add the '*' character is required if you use the variable somelists as provided by the OP.

          – brian buck
          Jan 13 '11 at 22:51




          1




          1





          @jaska: product() generates nitems_in_a_list ** nlists elements in the result (reduce(mul, map(len, somelists))). There is no reason to believe that yielding a single element is not O(nlists) (amortized) i.e., the time complexity is the same as for simple nested for-loops e.g., for the input in the question: nlists=3, total number of elements in the result: 3*2*2, and each element has nlists items (3 in this case).

          – jfs
          Aug 14 '15 at 22:08





          @jaska: product() generates nitems_in_a_list ** nlists elements in the result (reduce(mul, map(len, somelists))). There is no reason to believe that yielding a single element is not O(nlists) (amortized) i.e., the time complexity is the same as for simple nested for-loops e.g., for the input in the question: nlists=3, total number of elements in the result: 3*2*2, and each element has nlists items (3 in this case).

          – jfs
          Aug 14 '15 at 22:08




          2




          2





          What is the use of * before somelists? What does it do?

          – Vineet Kumar Doshi
          Aug 25 '15 at 9:04





          What is the use of * before somelists? What does it do?

          – Vineet Kumar Doshi
          Aug 25 '15 at 9:04




          6




          6





          @VineetKumarDoshi: Here it is used to unpcak a list into multiple arguments to the function call. Read more here: stackoverflow.com/questions/36901/…

          – Moberg
          Sep 15 '15 at 6:20





          @VineetKumarDoshi: Here it is used to unpcak a list into multiple arguments to the function call. Read more here: stackoverflow.com/questions/36901/…

          – Moberg
          Sep 15 '15 at 6:20




          3




          3





          Note: This works only if each list contains at least one item

          – igo
          Sep 13 '17 at 12:35





          Note: This works only if each list contains at least one item

          – igo
          Sep 13 '17 at 12:35













          68














          import itertools
          >>> for i in itertools.product([1,2,3],['a','b'],[4,5]):
          ... print i
          ...
          (1, 'a', 4)
          (1, 'a', 5)
          (1, 'b', 4)
          (1, 'b', 5)
          (2, 'a', 4)
          (2, 'a', 5)
          (2, 'b', 4)
          (2, 'b', 5)
          (3, 'a', 4)
          (3, 'a', 5)
          (3, 'b', 4)
          (3, 'b', 5)
          >>>





          share|improve this answer




























            68














            import itertools
            >>> for i in itertools.product([1,2,3],['a','b'],[4,5]):
            ... print i
            ...
            (1, 'a', 4)
            (1, 'a', 5)
            (1, 'b', 4)
            (1, 'b', 5)
            (2, 'a', 4)
            (2, 'a', 5)
            (2, 'b', 4)
            (2, 'b', 5)
            (3, 'a', 4)
            (3, 'a', 5)
            (3, 'b', 4)
            (3, 'b', 5)
            >>>





            share|improve this answer


























              68












              68








              68







              import itertools
              >>> for i in itertools.product([1,2,3],['a','b'],[4,5]):
              ... print i
              ...
              (1, 'a', 4)
              (1, 'a', 5)
              (1, 'b', 4)
              (1, 'b', 5)
              (2, 'a', 4)
              (2, 'a', 5)
              (2, 'b', 4)
              (2, 'b', 5)
              (3, 'a', 4)
              (3, 'a', 5)
              (3, 'b', 4)
              (3, 'b', 5)
              >>>





              share|improve this answer













              import itertools
              >>> for i in itertools.product([1,2,3],['a','b'],[4,5]):
              ... print i
              ...
              (1, 'a', 4)
              (1, 'a', 5)
              (1, 'b', 4)
              (1, 'b', 5)
              (2, 'a', 4)
              (2, 'a', 5)
              (2, 'b', 4)
              (2, 'b', 5)
              (3, 'a', 4)
              (3, 'a', 5)
              (3, 'b', 4)
              (3, 'b', 5)
              >>>






              share|improve this answer












              share|improve this answer



              share|improve this answer










              answered Feb 10 '09 at 19:58









              Jason BakerJason Baker

              106k109334488




              106k109334488























                  31














                  For Python 2.5 and older:



                  >>> [(a, b, c) for a in [1,2,3] for b in ['a','b'] for c in [4,5]]
                  [(1, 'a', 4), (1, 'a', 5), (1, 'b', 4), (1, 'b', 5), (2, 'a', 4),
                  (2, 'a', 5), (2, 'b', 4), (2, 'b', 5), (3, 'a', 4), (3, 'a', 5),
                  (3, 'b', 4), (3, 'b', 5)]


                  Here's a recursive version of product() (just an illustration):



                  def product(*args):
                  if not args:
                  return iter(((),)) # yield tuple()
                  return (items + (item,)
                  for items in product(*args[:-1]) for item in args[-1])


                  Example:



                  >>> list(product([1,2,3], ['a','b'], [4,5])) 
                  [(1, 'a', 4), (1, 'a', 5), (1, 'b', 4), (1, 'b', 5), (2, 'a', 4),
                  (2, 'a', 5), (2, 'b', 4), (2, 'b', 5), (3, 'a', 4), (3, 'a', 5),
                  (3, 'b', 4), (3, 'b', 5)]
                  >>> list(product([1,2,3]))
                  [(1,), (2,), (3,)]
                  >>> list(product())

                  >>> list(product())
                  [()]





                  share|improve this answer


























                  • The recursive version doesn't work if some of args are iterators.

                    – jfs
                    Feb 10 '09 at 21:43
















                  31














                  For Python 2.5 and older:



                  >>> [(a, b, c) for a in [1,2,3] for b in ['a','b'] for c in [4,5]]
                  [(1, 'a', 4), (1, 'a', 5), (1, 'b', 4), (1, 'b', 5), (2, 'a', 4),
                  (2, 'a', 5), (2, 'b', 4), (2, 'b', 5), (3, 'a', 4), (3, 'a', 5),
                  (3, 'b', 4), (3, 'b', 5)]


                  Here's a recursive version of product() (just an illustration):



                  def product(*args):
                  if not args:
                  return iter(((),)) # yield tuple()
                  return (items + (item,)
                  for items in product(*args[:-1]) for item in args[-1])


                  Example:



                  >>> list(product([1,2,3], ['a','b'], [4,5])) 
                  [(1, 'a', 4), (1, 'a', 5), (1, 'b', 4), (1, 'b', 5), (2, 'a', 4),
                  (2, 'a', 5), (2, 'b', 4), (2, 'b', 5), (3, 'a', 4), (3, 'a', 5),
                  (3, 'b', 4), (3, 'b', 5)]
                  >>> list(product([1,2,3]))
                  [(1,), (2,), (3,)]
                  >>> list(product())

                  >>> list(product())
                  [()]





                  share|improve this answer


























                  • The recursive version doesn't work if some of args are iterators.

                    – jfs
                    Feb 10 '09 at 21:43














                  31












                  31








                  31







                  For Python 2.5 and older:



                  >>> [(a, b, c) for a in [1,2,3] for b in ['a','b'] for c in [4,5]]
                  [(1, 'a', 4), (1, 'a', 5), (1, 'b', 4), (1, 'b', 5), (2, 'a', 4),
                  (2, 'a', 5), (2, 'b', 4), (2, 'b', 5), (3, 'a', 4), (3, 'a', 5),
                  (3, 'b', 4), (3, 'b', 5)]


                  Here's a recursive version of product() (just an illustration):



                  def product(*args):
                  if not args:
                  return iter(((),)) # yield tuple()
                  return (items + (item,)
                  for items in product(*args[:-1]) for item in args[-1])


                  Example:



                  >>> list(product([1,2,3], ['a','b'], [4,5])) 
                  [(1, 'a', 4), (1, 'a', 5), (1, 'b', 4), (1, 'b', 5), (2, 'a', 4),
                  (2, 'a', 5), (2, 'b', 4), (2, 'b', 5), (3, 'a', 4), (3, 'a', 5),
                  (3, 'b', 4), (3, 'b', 5)]
                  >>> list(product([1,2,3]))
                  [(1,), (2,), (3,)]
                  >>> list(product())

                  >>> list(product())
                  [()]





                  share|improve this answer















                  For Python 2.5 and older:



                  >>> [(a, b, c) for a in [1,2,3] for b in ['a','b'] for c in [4,5]]
                  [(1, 'a', 4), (1, 'a', 5), (1, 'b', 4), (1, 'b', 5), (2, 'a', 4),
                  (2, 'a', 5), (2, 'b', 4), (2, 'b', 5), (3, 'a', 4), (3, 'a', 5),
                  (3, 'b', 4), (3, 'b', 5)]


                  Here's a recursive version of product() (just an illustration):



                  def product(*args):
                  if not args:
                  return iter(((),)) # yield tuple()
                  return (items + (item,)
                  for items in product(*args[:-1]) for item in args[-1])


                  Example:



                  >>> list(product([1,2,3], ['a','b'], [4,5])) 
                  [(1, 'a', 4), (1, 'a', 5), (1, 'b', 4), (1, 'b', 5), (2, 'a', 4),
                  (2, 'a', 5), (2, 'b', 4), (2, 'b', 5), (3, 'a', 4), (3, 'a', 5),
                  (3, 'b', 4), (3, 'b', 5)]
                  >>> list(product([1,2,3]))
                  [(1,), (2,), (3,)]
                  >>> list(product())

                  >>> list(product())
                  [()]






                  share|improve this answer














                  share|improve this answer



                  share|improve this answer








                  edited Feb 10 '09 at 21:30

























                  answered Feb 10 '09 at 20:38









                  jfsjfs

                  266k815611102




                  266k815611102













                  • The recursive version doesn't work if some of args are iterators.

                    – jfs
                    Feb 10 '09 at 21:43



















                  • The recursive version doesn't work if some of args are iterators.

                    – jfs
                    Feb 10 '09 at 21:43

















                  The recursive version doesn't work if some of args are iterators.

                  – jfs
                  Feb 10 '09 at 21:43





                  The recursive version doesn't work if some of args are iterators.

                  – jfs
                  Feb 10 '09 at 21:43











                  17














                  with itertools.product:



                  import itertools
                  result = list(itertools.product(*somelists))





                  share|improve this answer





















                  • 5





                    What is the use of * before somelists?

                    – Vineet Kumar Doshi
                    Aug 25 '15 at 9:04











                  • @VineetKumarDoshi "product(somelists)" is a cartesian product between the sublists in a way that Python first get "[1, 2, 3]" as an element and then gets other element after next comman and that is linebreak so the first product term is ([1, 2, 3],), similary for the second ([4, 5],) and so "[([1, 2, 3],), ([4, 5],), ([6, 7],)]". If you wanna get a cartesian product between elements inside the tuples, you need to tell Python with Asterisk about the tuple structure. For dictionary, you use **. More here.

                    – hhh
                    Feb 15 '16 at 23:13
















                  17














                  with itertools.product:



                  import itertools
                  result = list(itertools.product(*somelists))





                  share|improve this answer





















                  • 5





                    What is the use of * before somelists?

                    – Vineet Kumar Doshi
                    Aug 25 '15 at 9:04











                  • @VineetKumarDoshi "product(somelists)" is a cartesian product between the sublists in a way that Python first get "[1, 2, 3]" as an element and then gets other element after next comman and that is linebreak so the first product term is ([1, 2, 3],), similary for the second ([4, 5],) and so "[([1, 2, 3],), ([4, 5],), ([6, 7],)]". If you wanna get a cartesian product between elements inside the tuples, you need to tell Python with Asterisk about the tuple structure. For dictionary, you use **. More here.

                    – hhh
                    Feb 15 '16 at 23:13














                  17












                  17








                  17







                  with itertools.product:



                  import itertools
                  result = list(itertools.product(*somelists))





                  share|improve this answer















                  with itertools.product:



                  import itertools
                  result = list(itertools.product(*somelists))






                  share|improve this answer














                  share|improve this answer



                  share|improve this answer








                  edited Jan 1 '10 at 17:03

























                  answered Feb 10 '09 at 20:01









                  SilentGhostSilentGhost

                  195k47266263




                  195k47266263








                  • 5





                    What is the use of * before somelists?

                    – Vineet Kumar Doshi
                    Aug 25 '15 at 9:04











                  • @VineetKumarDoshi "product(somelists)" is a cartesian product between the sublists in a way that Python first get "[1, 2, 3]" as an element and then gets other element after next comman and that is linebreak so the first product term is ([1, 2, 3],), similary for the second ([4, 5],) and so "[([1, 2, 3],), ([4, 5],), ([6, 7],)]". If you wanna get a cartesian product between elements inside the tuples, you need to tell Python with Asterisk about the tuple structure. For dictionary, you use **. More here.

                    – hhh
                    Feb 15 '16 at 23:13














                  • 5





                    What is the use of * before somelists?

                    – Vineet Kumar Doshi
                    Aug 25 '15 at 9:04











                  • @VineetKumarDoshi "product(somelists)" is a cartesian product between the sublists in a way that Python first get "[1, 2, 3]" as an element and then gets other element after next comman and that is linebreak so the first product term is ([1, 2, 3],), similary for the second ([4, 5],) and so "[([1, 2, 3],), ([4, 5],), ([6, 7],)]". If you wanna get a cartesian product between elements inside the tuples, you need to tell Python with Asterisk about the tuple structure. For dictionary, you use **. More here.

                    – hhh
                    Feb 15 '16 at 23:13








                  5




                  5





                  What is the use of * before somelists?

                  – Vineet Kumar Doshi
                  Aug 25 '15 at 9:04





                  What is the use of * before somelists?

                  – Vineet Kumar Doshi
                  Aug 25 '15 at 9:04













                  @VineetKumarDoshi "product(somelists)" is a cartesian product between the sublists in a way that Python first get "[1, 2, 3]" as an element and then gets other element after next comman and that is linebreak so the first product term is ([1, 2, 3],), similary for the second ([4, 5],) and so "[([1, 2, 3],), ([4, 5],), ([6, 7],)]". If you wanna get a cartesian product between elements inside the tuples, you need to tell Python with Asterisk about the tuple structure. For dictionary, you use **. More here.

                  – hhh
                  Feb 15 '16 at 23:13





                  @VineetKumarDoshi "product(somelists)" is a cartesian product between the sublists in a way that Python first get "[1, 2, 3]" as an element and then gets other element after next comman and that is linebreak so the first product term is ([1, 2, 3],), similary for the second ([4, 5],) and so "[([1, 2, 3],), ([4, 5],), ([6, 7],)]". If you wanna get a cartesian product between elements inside the tuples, you need to tell Python with Asterisk about the tuple structure. For dictionary, you use **. More here.

                  – hhh
                  Feb 15 '16 at 23:13











                  11














                  In Python 2.6 and above you can use 'itertools.product`. In older versions of Python you can use the following (almost -- see documentation) equivalent code from the documentation, at least as a starting point:



                  def product(*args, **kwds):
                  # product('ABCD', 'xy') --> Ax Ay Bx By Cx Cy Dx Dy
                  # product(range(2), repeat=3) --> 000 001 010 011 100 101 110 111
                  pools = map(tuple, args) * kwds.get('repeat', 1)
                  result = []
                  for pool in pools:
                  result = [x+[y] for x in result for y in pool]
                  for prod in result:
                  yield tuple(prod)


                  The result of both is an iterator, so if you really need a list for furthert processing, use list(result).






                  share|improve this answer


























                  • Per the documentation, the actual itertools.product implementation does NOT build intermediate results, which could be expensive. Using this technique could get out of hand quite quickly for moderately sized lists.

                    – Triptych
                    Feb 10 '09 at 20:05






                  • 3





                    i can only point the OP to the documentation, not read it for him.

                    – user3850
                    Feb 10 '09 at 20:19






                  • 1





                    The code from the documentation is meant to demonstrate what the product function does, not as a workaround for earlier versions of Python.

                    – Triptych
                    Mar 10 '09 at 21:07






                  • 2





                    your point being?

                    – user3850
                    Mar 10 '09 at 22:37
















                  11














                  In Python 2.6 and above you can use 'itertools.product`. In older versions of Python you can use the following (almost -- see documentation) equivalent code from the documentation, at least as a starting point:



                  def product(*args, **kwds):
                  # product('ABCD', 'xy') --> Ax Ay Bx By Cx Cy Dx Dy
                  # product(range(2), repeat=3) --> 000 001 010 011 100 101 110 111
                  pools = map(tuple, args) * kwds.get('repeat', 1)
                  result = []
                  for pool in pools:
                  result = [x+[y] for x in result for y in pool]
                  for prod in result:
                  yield tuple(prod)


                  The result of both is an iterator, so if you really need a list for furthert processing, use list(result).






                  share|improve this answer


























                  • Per the documentation, the actual itertools.product implementation does NOT build intermediate results, which could be expensive. Using this technique could get out of hand quite quickly for moderately sized lists.

                    – Triptych
                    Feb 10 '09 at 20:05






                  • 3





                    i can only point the OP to the documentation, not read it for him.

                    – user3850
                    Feb 10 '09 at 20:19






                  • 1





                    The code from the documentation is meant to demonstrate what the product function does, not as a workaround for earlier versions of Python.

                    – Triptych
                    Mar 10 '09 at 21:07






                  • 2





                    your point being?

                    – user3850
                    Mar 10 '09 at 22:37














                  11












                  11








                  11







                  In Python 2.6 and above you can use 'itertools.product`. In older versions of Python you can use the following (almost -- see documentation) equivalent code from the documentation, at least as a starting point:



                  def product(*args, **kwds):
                  # product('ABCD', 'xy') --> Ax Ay Bx By Cx Cy Dx Dy
                  # product(range(2), repeat=3) --> 000 001 010 011 100 101 110 111
                  pools = map(tuple, args) * kwds.get('repeat', 1)
                  result = []
                  for pool in pools:
                  result = [x+[y] for x in result for y in pool]
                  for prod in result:
                  yield tuple(prod)


                  The result of both is an iterator, so if you really need a list for furthert processing, use list(result).






                  share|improve this answer















                  In Python 2.6 and above you can use 'itertools.product`. In older versions of Python you can use the following (almost -- see documentation) equivalent code from the documentation, at least as a starting point:



                  def product(*args, **kwds):
                  # product('ABCD', 'xy') --> Ax Ay Bx By Cx Cy Dx Dy
                  # product(range(2), repeat=3) --> 000 001 010 011 100 101 110 111
                  pools = map(tuple, args) * kwds.get('repeat', 1)
                  result = []
                  for pool in pools:
                  result = [x+[y] for x in result for y in pool]
                  for prod in result:
                  yield tuple(prod)


                  The result of both is an iterator, so if you really need a list for furthert processing, use list(result).







                  share|improve this answer














                  share|improve this answer



                  share|improve this answer








                  edited Jan 5 '17 at 14:30

























                  answered Feb 10 '09 at 20:02







                  user3850




















                  • Per the documentation, the actual itertools.product implementation does NOT build intermediate results, which could be expensive. Using this technique could get out of hand quite quickly for moderately sized lists.

                    – Triptych
                    Feb 10 '09 at 20:05






                  • 3





                    i can only point the OP to the documentation, not read it for him.

                    – user3850
                    Feb 10 '09 at 20:19






                  • 1





                    The code from the documentation is meant to demonstrate what the product function does, not as a workaround for earlier versions of Python.

                    – Triptych
                    Mar 10 '09 at 21:07






                  • 2





                    your point being?

                    – user3850
                    Mar 10 '09 at 22:37



















                  • Per the documentation, the actual itertools.product implementation does NOT build intermediate results, which could be expensive. Using this technique could get out of hand quite quickly for moderately sized lists.

                    – Triptych
                    Feb 10 '09 at 20:05






                  • 3





                    i can only point the OP to the documentation, not read it for him.

                    – user3850
                    Feb 10 '09 at 20:19






                  • 1





                    The code from the documentation is meant to demonstrate what the product function does, not as a workaround for earlier versions of Python.

                    – Triptych
                    Mar 10 '09 at 21:07






                  • 2





                    your point being?

                    – user3850
                    Mar 10 '09 at 22:37

















                  Per the documentation, the actual itertools.product implementation does NOT build intermediate results, which could be expensive. Using this technique could get out of hand quite quickly for moderately sized lists.

                  – Triptych
                  Feb 10 '09 at 20:05





                  Per the documentation, the actual itertools.product implementation does NOT build intermediate results, which could be expensive. Using this technique could get out of hand quite quickly for moderately sized lists.

                  – Triptych
                  Feb 10 '09 at 20:05




                  3




                  3





                  i can only point the OP to the documentation, not read it for him.

                  – user3850
                  Feb 10 '09 at 20:19





                  i can only point the OP to the documentation, not read it for him.

                  – user3850
                  Feb 10 '09 at 20:19




                  1




                  1





                  The code from the documentation is meant to demonstrate what the product function does, not as a workaround for earlier versions of Python.

                  – Triptych
                  Mar 10 '09 at 21:07





                  The code from the documentation is meant to demonstrate what the product function does, not as a workaround for earlier versions of Python.

                  – Triptych
                  Mar 10 '09 at 21:07




                  2




                  2





                  your point being?

                  – user3850
                  Mar 10 '09 at 22:37





                  your point being?

                  – user3850
                  Mar 10 '09 at 22:37











                  10














                  I would use list comprehension :



                  somelists = [
                  [1, 2, 3],
                  ['a', 'b'],
                  [4, 5]
                  ]

                  cart_prod = [(a,b,c) for a in somelists[0] for b in somelists[1] for c in somelists[2]]





                  share|improve this answer
























                  • I really like this solution using list comprehensions. I don't know why isn't upvoted more, it's so simple.

                    – llekn
                    Nov 30 '16 at 17:38






                  • 9





                    @llekn because the code seems to be fixed to the number of lists

                    – Bằng Rikimaru
                    Jan 16 '17 at 15:33
















                  10














                  I would use list comprehension :



                  somelists = [
                  [1, 2, 3],
                  ['a', 'b'],
                  [4, 5]
                  ]

                  cart_prod = [(a,b,c) for a in somelists[0] for b in somelists[1] for c in somelists[2]]





                  share|improve this answer
























                  • I really like this solution using list comprehensions. I don't know why isn't upvoted more, it's so simple.

                    – llekn
                    Nov 30 '16 at 17:38






                  • 9





                    @llekn because the code seems to be fixed to the number of lists

                    – Bằng Rikimaru
                    Jan 16 '17 at 15:33














                  10












                  10








                  10







                  I would use list comprehension :



                  somelists = [
                  [1, 2, 3],
                  ['a', 'b'],
                  [4, 5]
                  ]

                  cart_prod = [(a,b,c) for a in somelists[0] for b in somelists[1] for c in somelists[2]]





                  share|improve this answer













                  I would use list comprehension :



                  somelists = [
                  [1, 2, 3],
                  ['a', 'b'],
                  [4, 5]
                  ]

                  cart_prod = [(a,b,c) for a in somelists[0] for b in somelists[1] for c in somelists[2]]






                  share|improve this answer












                  share|improve this answer



                  share|improve this answer










                  answered Nov 21 '16 at 8:42









                  user1035648user1035648

                  13416




                  13416













                  • I really like this solution using list comprehensions. I don't know why isn't upvoted more, it's so simple.

                    – llekn
                    Nov 30 '16 at 17:38






                  • 9





                    @llekn because the code seems to be fixed to the number of lists

                    – Bằng Rikimaru
                    Jan 16 '17 at 15:33



















                  • I really like this solution using list comprehensions. I don't know why isn't upvoted more, it's so simple.

                    – llekn
                    Nov 30 '16 at 17:38






                  • 9





                    @llekn because the code seems to be fixed to the number of lists

                    – Bằng Rikimaru
                    Jan 16 '17 at 15:33

















                  I really like this solution using list comprehensions. I don't know why isn't upvoted more, it's so simple.

                  – llekn
                  Nov 30 '16 at 17:38





                  I really like this solution using list comprehensions. I don't know why isn't upvoted more, it's so simple.

                  – llekn
                  Nov 30 '16 at 17:38




                  9




                  9





                  @llekn because the code seems to be fixed to the number of lists

                  – Bằng Rikimaru
                  Jan 16 '17 at 15:33





                  @llekn because the code seems to be fixed to the number of lists

                  – Bằng Rikimaru
                  Jan 16 '17 at 15:33











                  9














                  Here is a recursive generator, which doesn't store any temporary lists



                  def product(ar_list):
                  if not ar_list:
                  yield ()
                  else:
                  for a in ar_list[0]:
                  for prod in product(ar_list[1:]):
                  yield (a,)+prod

                  print list(product([[1,2],[3,4],[5,6]]))


                  Output:



                  [(1, 3, 5), (1, 3, 6), (1, 4, 5), (1, 4, 6), (2, 3, 5), (2, 3, 6), (2, 4, 5), (2, 4, 6)]





                  share|improve this answer



















                  • 1





                    They're stored in the stack, though.

                    – Quentin Pradet
                    Mar 16 '15 at 11:09











                  • @QuentinPradet do you mean a generator like def f(): while True: yield 1 will keep on increasing its stack size as we go through it?

                    – Anurag Uniyal
                    Mar 16 '15 at 22:42













                  • no, but def f(): yield 1; f() will, right?

                    – Quentin Pradet
                    Mar 17 '15 at 10:09











                  • @QuentinPradet yeah, but even in this case only the stack needed for max depth, not the whole list, so in this case stack of 3

                    – Anurag Uniyal
                    Mar 17 '15 at 16:14













                  • It's true, sorry. A benchmark could be interesting. :)

                    – Quentin Pradet
                    Mar 17 '15 at 18:24
















                  9














                  Here is a recursive generator, which doesn't store any temporary lists



                  def product(ar_list):
                  if not ar_list:
                  yield ()
                  else:
                  for a in ar_list[0]:
                  for prod in product(ar_list[1:]):
                  yield (a,)+prod

                  print list(product([[1,2],[3,4],[5,6]]))


                  Output:



                  [(1, 3, 5), (1, 3, 6), (1, 4, 5), (1, 4, 6), (2, 3, 5), (2, 3, 6), (2, 4, 5), (2, 4, 6)]





                  share|improve this answer



















                  • 1





                    They're stored in the stack, though.

                    – Quentin Pradet
                    Mar 16 '15 at 11:09











                  • @QuentinPradet do you mean a generator like def f(): while True: yield 1 will keep on increasing its stack size as we go through it?

                    – Anurag Uniyal
                    Mar 16 '15 at 22:42













                  • no, but def f(): yield 1; f() will, right?

                    – Quentin Pradet
                    Mar 17 '15 at 10:09











                  • @QuentinPradet yeah, but even in this case only the stack needed for max depth, not the whole list, so in this case stack of 3

                    – Anurag Uniyal
                    Mar 17 '15 at 16:14













                  • It's true, sorry. A benchmark could be interesting. :)

                    – Quentin Pradet
                    Mar 17 '15 at 18:24














                  9












                  9








                  9







                  Here is a recursive generator, which doesn't store any temporary lists



                  def product(ar_list):
                  if not ar_list:
                  yield ()
                  else:
                  for a in ar_list[0]:
                  for prod in product(ar_list[1:]):
                  yield (a,)+prod

                  print list(product([[1,2],[3,4],[5,6]]))


                  Output:



                  [(1, 3, 5), (1, 3, 6), (1, 4, 5), (1, 4, 6), (2, 3, 5), (2, 3, 6), (2, 4, 5), (2, 4, 6)]





                  share|improve this answer













                  Here is a recursive generator, which doesn't store any temporary lists



                  def product(ar_list):
                  if not ar_list:
                  yield ()
                  else:
                  for a in ar_list[0]:
                  for prod in product(ar_list[1:]):
                  yield (a,)+prod

                  print list(product([[1,2],[3,4],[5,6]]))


                  Output:



                  [(1, 3, 5), (1, 3, 6), (1, 4, 5), (1, 4, 6), (2, 3, 5), (2, 3, 6), (2, 4, 5), (2, 4, 6)]






                  share|improve this answer












                  share|improve this answer



                  share|improve this answer










                  answered Jun 14 '13 at 6:08









                  Anurag UniyalAnurag Uniyal

                  55.6k28148198




                  55.6k28148198








                  • 1





                    They're stored in the stack, though.

                    – Quentin Pradet
                    Mar 16 '15 at 11:09











                  • @QuentinPradet do you mean a generator like def f(): while True: yield 1 will keep on increasing its stack size as we go through it?

                    – Anurag Uniyal
                    Mar 16 '15 at 22:42













                  • no, but def f(): yield 1; f() will, right?

                    – Quentin Pradet
                    Mar 17 '15 at 10:09











                  • @QuentinPradet yeah, but even in this case only the stack needed for max depth, not the whole list, so in this case stack of 3

                    – Anurag Uniyal
                    Mar 17 '15 at 16:14













                  • It's true, sorry. A benchmark could be interesting. :)

                    – Quentin Pradet
                    Mar 17 '15 at 18:24














                  • 1





                    They're stored in the stack, though.

                    – Quentin Pradet
                    Mar 16 '15 at 11:09











                  • @QuentinPradet do you mean a generator like def f(): while True: yield 1 will keep on increasing its stack size as we go through it?

                    – Anurag Uniyal
                    Mar 16 '15 at 22:42













                  • no, but def f(): yield 1; f() will, right?

                    – Quentin Pradet
                    Mar 17 '15 at 10:09











                  • @QuentinPradet yeah, but even in this case only the stack needed for max depth, not the whole list, so in this case stack of 3

                    – Anurag Uniyal
                    Mar 17 '15 at 16:14













                  • It's true, sorry. A benchmark could be interesting. :)

                    – Quentin Pradet
                    Mar 17 '15 at 18:24








                  1




                  1





                  They're stored in the stack, though.

                  – Quentin Pradet
                  Mar 16 '15 at 11:09





                  They're stored in the stack, though.

                  – Quentin Pradet
                  Mar 16 '15 at 11:09













                  @QuentinPradet do you mean a generator like def f(): while True: yield 1 will keep on increasing its stack size as we go through it?

                  – Anurag Uniyal
                  Mar 16 '15 at 22:42







                  @QuentinPradet do you mean a generator like def f(): while True: yield 1 will keep on increasing its stack size as we go through it?

                  – Anurag Uniyal
                  Mar 16 '15 at 22:42















                  no, but def f(): yield 1; f() will, right?

                  – Quentin Pradet
                  Mar 17 '15 at 10:09





                  no, but def f(): yield 1; f() will, right?

                  – Quentin Pradet
                  Mar 17 '15 at 10:09













                  @QuentinPradet yeah, but even in this case only the stack needed for max depth, not the whole list, so in this case stack of 3

                  – Anurag Uniyal
                  Mar 17 '15 at 16:14







                  @QuentinPradet yeah, but even in this case only the stack needed for max depth, not the whole list, so in this case stack of 3

                  – Anurag Uniyal
                  Mar 17 '15 at 16:14















                  It's true, sorry. A benchmark could be interesting. :)

                  – Quentin Pradet
                  Mar 17 '15 at 18:24





                  It's true, sorry. A benchmark could be interesting. :)

                  – Quentin Pradet
                  Mar 17 '15 at 18:24











                  6














                  Although there are many answers already, I would like to share some of my thoughts:



                  Iterative approach



                  def cartesian_iterative(pools):
                  result = []
                  for pool in pools:
                  result = [x+[y] for x in result for y in pool]
                  return result


                  Recursive Approach



                  def cartesian_recursive(pools):
                  if len(pools) > 2:
                  pools[0] = product(pools[0], pools[1])
                  del pools[1]
                  return cartesian_recursive(pools)
                  else:
                  pools[0] = product(pools[0], pools[1])
                  del pools[1]
                  return pools
                  def product(x, y):
                  return [xx + [yy] if isinstance(xx, list) else [xx] + [yy] for xx in x for yy in y]


                  Lambda Approach



                  def cartesian_reduct(pools):
                  return reduce(lambda x,y: product(x,y) , pools)





                  share|improve this answer


























                  • In "Iterative Approach", why is result declared as result = [] I know that it is list_of_list but in general even if we have declare list_of_list we use and not []

                    – Sachin S
                    Jul 16 '17 at 15:44











                  • I'm a bit of a newby in terms of Pythonic solutions. Would you or some passerby please write the list comprehension in the "iterative approach" in separate loops?

                    – Johnny Boy
                    Dec 10 '18 at 17:03
















                  6














                  Although there are many answers already, I would like to share some of my thoughts:



                  Iterative approach



                  def cartesian_iterative(pools):
                  result = []
                  for pool in pools:
                  result = [x+[y] for x in result for y in pool]
                  return result


                  Recursive Approach



                  def cartesian_recursive(pools):
                  if len(pools) > 2:
                  pools[0] = product(pools[0], pools[1])
                  del pools[1]
                  return cartesian_recursive(pools)
                  else:
                  pools[0] = product(pools[0], pools[1])
                  del pools[1]
                  return pools
                  def product(x, y):
                  return [xx + [yy] if isinstance(xx, list) else [xx] + [yy] for xx in x for yy in y]


                  Lambda Approach



                  def cartesian_reduct(pools):
                  return reduce(lambda x,y: product(x,y) , pools)





                  share|improve this answer


























                  • In "Iterative Approach", why is result declared as result = [] I know that it is list_of_list but in general even if we have declare list_of_list we use and not []

                    – Sachin S
                    Jul 16 '17 at 15:44











                  • I'm a bit of a newby in terms of Pythonic solutions. Would you or some passerby please write the list comprehension in the "iterative approach" in separate loops?

                    – Johnny Boy
                    Dec 10 '18 at 17:03














                  6












                  6








                  6







                  Although there are many answers already, I would like to share some of my thoughts:



                  Iterative approach



                  def cartesian_iterative(pools):
                  result = []
                  for pool in pools:
                  result = [x+[y] for x in result for y in pool]
                  return result


                  Recursive Approach



                  def cartesian_recursive(pools):
                  if len(pools) > 2:
                  pools[0] = product(pools[0], pools[1])
                  del pools[1]
                  return cartesian_recursive(pools)
                  else:
                  pools[0] = product(pools[0], pools[1])
                  del pools[1]
                  return pools
                  def product(x, y):
                  return [xx + [yy] if isinstance(xx, list) else [xx] + [yy] for xx in x for yy in y]


                  Lambda Approach



                  def cartesian_reduct(pools):
                  return reduce(lambda x,y: product(x,y) , pools)





                  share|improve this answer















                  Although there are many answers already, I would like to share some of my thoughts:



                  Iterative approach



                  def cartesian_iterative(pools):
                  result = []
                  for pool in pools:
                  result = [x+[y] for x in result for y in pool]
                  return result


                  Recursive Approach



                  def cartesian_recursive(pools):
                  if len(pools) > 2:
                  pools[0] = product(pools[0], pools[1])
                  del pools[1]
                  return cartesian_recursive(pools)
                  else:
                  pools[0] = product(pools[0], pools[1])
                  del pools[1]
                  return pools
                  def product(x, y):
                  return [xx + [yy] if isinstance(xx, list) else [xx] + [yy] for xx in x for yy in y]


                  Lambda Approach



                  def cartesian_reduct(pools):
                  return reduce(lambda x,y: product(x,y) , pools)






                  share|improve this answer














                  share|improve this answer



                  share|improve this answer








                  edited Feb 21 '17 at 6:40









                  Matthew Beckman

                  1,15721025




                  1,15721025










                  answered Feb 21 '17 at 4:03









                  weiyixieweiyixie

                  22733




                  22733













                  • In "Iterative Approach", why is result declared as result = [] I know that it is list_of_list but in general even if we have declare list_of_list we use and not []

                    – Sachin S
                    Jul 16 '17 at 15:44











                  • I'm a bit of a newby in terms of Pythonic solutions. Would you or some passerby please write the list comprehension in the "iterative approach" in separate loops?

                    – Johnny Boy
                    Dec 10 '18 at 17:03



















                  • In "Iterative Approach", why is result declared as result = [] I know that it is list_of_list but in general even if we have declare list_of_list we use and not []

                    – Sachin S
                    Jul 16 '17 at 15:44











                  • I'm a bit of a newby in terms of Pythonic solutions. Would you or some passerby please write the list comprehension in the "iterative approach" in separate loops?

                    – Johnny Boy
                    Dec 10 '18 at 17:03

















                  In "Iterative Approach", why is result declared as result = [] I know that it is list_of_list but in general even if we have declare list_of_list we use and not []

                  – Sachin S
                  Jul 16 '17 at 15:44





                  In "Iterative Approach", why is result declared as result = [] I know that it is list_of_list but in general even if we have declare list_of_list we use and not []

                  – Sachin S
                  Jul 16 '17 at 15:44













                  I'm a bit of a newby in terms of Pythonic solutions. Would you or some passerby please write the list comprehension in the "iterative approach" in separate loops?

                  – Johnny Boy
                  Dec 10 '18 at 17:03





                  I'm a bit of a newby in terms of Pythonic solutions. Would you or some passerby please write the list comprehension in the "iterative approach" in separate loops?

                  – Johnny Boy
                  Dec 10 '18 at 17:03











                  2














                  Just to add a bit to what has already been said: if you use sympy, you can use symbols rather than strings which makes them mathematically useful.



                  import itertools
                  import sympy

                  x, y = sympy.symbols('x y')

                  somelist = [[x,y], [1,2,3], [4,5]]
                  somelist2 = [[1,2], [1,2,3], [4,5]]

                  for element in itertools.product(*somelist):
                  print element


                  About sympy.






                  share|improve this answer






























                    2














                    Just to add a bit to what has already been said: if you use sympy, you can use symbols rather than strings which makes them mathematically useful.



                    import itertools
                    import sympy

                    x, y = sympy.symbols('x y')

                    somelist = [[x,y], [1,2,3], [4,5]]
                    somelist2 = [[1,2], [1,2,3], [4,5]]

                    for element in itertools.product(*somelist):
                    print element


                    About sympy.






                    share|improve this answer




























                      2












                      2








                      2







                      Just to add a bit to what has already been said: if you use sympy, you can use symbols rather than strings which makes them mathematically useful.



                      import itertools
                      import sympy

                      x, y = sympy.symbols('x y')

                      somelist = [[x,y], [1,2,3], [4,5]]
                      somelist2 = [[1,2], [1,2,3], [4,5]]

                      for element in itertools.product(*somelist):
                      print element


                      About sympy.






                      share|improve this answer















                      Just to add a bit to what has already been said: if you use sympy, you can use symbols rather than strings which makes them mathematically useful.



                      import itertools
                      import sympy

                      x, y = sympy.symbols('x y')

                      somelist = [[x,y], [1,2,3], [4,5]]
                      somelist2 = [[1,2], [1,2,3], [4,5]]

                      for element in itertools.product(*somelist):
                      print element


                      About sympy.







                      share|improve this answer














                      share|improve this answer



                      share|improve this answer








                      edited Jun 8 '16 at 6:47









                      FengYao

                      114




                      114










                      answered Oct 29 '15 at 22:28









                      Tyler HeersTyler Heers

                      1164




                      1164























                          2














                          A minor modification to the above recursive generator solution in variadic flavor:



                          def product_args(*args):
                          if args:
                          for a in args[0]:
                          for prod in product_args(*args[1:]) if args[1:] else ((),):
                          yield (a,) + prod


                          And of course a wrapper which makes it work exactly the same as that solution:



                          def product2(ar_list):
                          """
                          >>> list(product(()))
                          [()]
                          >>> list(product2(()))

                          """
                          return product_args(*ar_list)


                          with one trade-off: it checks if recursion should break upon each outer loop, and one gain: no yield upon empty call, e.g.product(()), which I suppose would be semantically more correct (see the doctest).



                          Regarding list comprehension: the mathematical definition applies to an arbitrary number of arguments, while list comprehension could only deal with a known number of them.






                          share|improve this answer






























                            2














                            A minor modification to the above recursive generator solution in variadic flavor:



                            def product_args(*args):
                            if args:
                            for a in args[0]:
                            for prod in product_args(*args[1:]) if args[1:] else ((),):
                            yield (a,) + prod


                            And of course a wrapper which makes it work exactly the same as that solution:



                            def product2(ar_list):
                            """
                            >>> list(product(()))
                            [()]
                            >>> list(product2(()))

                            """
                            return product_args(*ar_list)


                            with one trade-off: it checks if recursion should break upon each outer loop, and one gain: no yield upon empty call, e.g.product(()), which I suppose would be semantically more correct (see the doctest).



                            Regarding list comprehension: the mathematical definition applies to an arbitrary number of arguments, while list comprehension could only deal with a known number of them.






                            share|improve this answer




























                              2












                              2








                              2







                              A minor modification to the above recursive generator solution in variadic flavor:



                              def product_args(*args):
                              if args:
                              for a in args[0]:
                              for prod in product_args(*args[1:]) if args[1:] else ((),):
                              yield (a,) + prod


                              And of course a wrapper which makes it work exactly the same as that solution:



                              def product2(ar_list):
                              """
                              >>> list(product(()))
                              [()]
                              >>> list(product2(()))

                              """
                              return product_args(*ar_list)


                              with one trade-off: it checks if recursion should break upon each outer loop, and one gain: no yield upon empty call, e.g.product(()), which I suppose would be semantically more correct (see the doctest).



                              Regarding list comprehension: the mathematical definition applies to an arbitrary number of arguments, while list comprehension could only deal with a known number of them.






                              share|improve this answer















                              A minor modification to the above recursive generator solution in variadic flavor:



                              def product_args(*args):
                              if args:
                              for a in args[0]:
                              for prod in product_args(*args[1:]) if args[1:] else ((),):
                              yield (a,) + prod


                              And of course a wrapper which makes it work exactly the same as that solution:



                              def product2(ar_list):
                              """
                              >>> list(product(()))
                              [()]
                              >>> list(product2(()))

                              """
                              return product_args(*ar_list)


                              with one trade-off: it checks if recursion should break upon each outer loop, and one gain: no yield upon empty call, e.g.product(()), which I suppose would be semantically more correct (see the doctest).



                              Regarding list comprehension: the mathematical definition applies to an arbitrary number of arguments, while list comprehension could only deal with a known number of them.







                              share|improve this answer














                              share|improve this answer



                              share|improve this answer








                              edited Jan 11 '18 at 22:56









                              user3759769

                              52




                              52










                              answered Dec 10 '16 at 1:40









                              Mike LuMike Lu

                              212




                              212























                                  1














                                  Recursive Approach:



                                  def rec_cart(start, array, partial, results):
                                  if len(partial) == len(array):
                                  results.append(partial)
                                  return

                                  for element in array[start]:
                                  rec_cart(start+1, array, partial+[element], results)

                                  rec_res =
                                  some_lists = [[1, 2, 3], ['a', 'b'], [4, 5]]
                                  rec_cart(0, some_lists, , rec_res)
                                  print(rec_res)


                                  Iterative Approach:



                                  def itr_cart(array):
                                  results = []
                                  for i in range(len(array)):
                                  temp =
                                  for res in results:
                                  for element in array[i]:
                                  temp.append(res+[element])
                                  results = temp

                                  return results

                                  some_lists = [[1, 2, 3], ['a', 'b'], [4, 5]]
                                  itr_res = itr_cart(some_lists)
                                  print(itr_res)





                                  share|improve this answer




























                                    1














                                    Recursive Approach:



                                    def rec_cart(start, array, partial, results):
                                    if len(partial) == len(array):
                                    results.append(partial)
                                    return

                                    for element in array[start]:
                                    rec_cart(start+1, array, partial+[element], results)

                                    rec_res =
                                    some_lists = [[1, 2, 3], ['a', 'b'], [4, 5]]
                                    rec_cart(0, some_lists, , rec_res)
                                    print(rec_res)


                                    Iterative Approach:



                                    def itr_cart(array):
                                    results = []
                                    for i in range(len(array)):
                                    temp =
                                    for res in results:
                                    for element in array[i]:
                                    temp.append(res+[element])
                                    results = temp

                                    return results

                                    some_lists = [[1, 2, 3], ['a', 'b'], [4, 5]]
                                    itr_res = itr_cart(some_lists)
                                    print(itr_res)





                                    share|improve this answer


























                                      1












                                      1








                                      1







                                      Recursive Approach:



                                      def rec_cart(start, array, partial, results):
                                      if len(partial) == len(array):
                                      results.append(partial)
                                      return

                                      for element in array[start]:
                                      rec_cart(start+1, array, partial+[element], results)

                                      rec_res =
                                      some_lists = [[1, 2, 3], ['a', 'b'], [4, 5]]
                                      rec_cart(0, some_lists, , rec_res)
                                      print(rec_res)


                                      Iterative Approach:



                                      def itr_cart(array):
                                      results = []
                                      for i in range(len(array)):
                                      temp =
                                      for res in results:
                                      for element in array[i]:
                                      temp.append(res+[element])
                                      results = temp

                                      return results

                                      some_lists = [[1, 2, 3], ['a', 'b'], [4, 5]]
                                      itr_res = itr_cart(some_lists)
                                      print(itr_res)





                                      share|improve this answer













                                      Recursive Approach:



                                      def rec_cart(start, array, partial, results):
                                      if len(partial) == len(array):
                                      results.append(partial)
                                      return

                                      for element in array[start]:
                                      rec_cart(start+1, array, partial+[element], results)

                                      rec_res =
                                      some_lists = [[1, 2, 3], ['a', 'b'], [4, 5]]
                                      rec_cart(0, some_lists, , rec_res)
                                      print(rec_res)


                                      Iterative Approach:



                                      def itr_cart(array):
                                      results = []
                                      for i in range(len(array)):
                                      temp =
                                      for res in results:
                                      for element in array[i]:
                                      temp.append(res+[element])
                                      results = temp

                                      return results

                                      some_lists = [[1, 2, 3], ['a', 'b'], [4, 5]]
                                      itr_res = itr_cart(some_lists)
                                      print(itr_res)






                                      share|improve this answer












                                      share|improve this answer



                                      share|improve this answer










                                      answered Dec 31 '18 at 18:32









                                      JaiJai

                                      1,5722616




                                      1,5722616






























                                          draft saved

                                          draft discarded




















































                                          Thanks for contributing an answer to Stack Overflow!


                                          • Please be sure to answer the question. Provide details and share your research!

                                          But avoid



                                          • Asking for help, clarification, or responding to other answers.

                                          • Making statements based on opinion; back them up with references or personal experience.


                                          To learn more, see our tips on writing great answers.




                                          draft saved


                                          draft discarded














                                          StackExchange.ready(
                                          function () {
                                          StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f533905%2fget-the-cartesian-product-of-a-series-of-lists%23new-answer', 'question_page');
                                          }
                                          );

                                          Post as a guest















                                          Required, but never shown





















































                                          Required, but never shown














                                          Required, but never shown












                                          Required, but never shown







                                          Required, but never shown

































                                          Required, but never shown














                                          Required, but never shown












                                          Required, but never shown







                                          Required, but never shown







                                          Popular posts from this blog

                                          Biblatex bibliography style without URLs when DOI exists (in Overleaf with Zotero bibliography)

                                          ComboBox Display Member on multiple fields

                                          Is it possible to collect Nectar points via Trainline?