Compute the product of 3 dictionaries and concatenate keys and values





.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty{ height:90px;width:728px;box-sizing:border-box;
}







8















Assuming that I have 3 different dictionaries:



dict1 = {
"A": "a"
}

dict2 = {
"B": "b",
"C": "c",
"D": "d",
"E": "e"
}

dict3 = {
"F": "f",
"G": "g"
}


I want to compute the product of these dictionaries (excluding the product between dict2 and dict3) and combine both the keys and values where the keys are concatenated with _ and values with ' and '



The desired output would be a single dictionary:



{
# dict1 x dict2
"A_B": "a and b",
"A_C": "a and c",
"A_D": "a and d",
"A_E": "a and e",

# dict1 x dict3
"A_F": "a and f",
"A_G": "a and g",

# dict1 x dict2 x dict3
"A_B_F": "a and b and f",
"A_B_G": "a and b and g",
"A_C_F": "a and c and f",
"A_C_G": "a and c and g",
"A_D_F": "a and d and f",
"A_D_G": "a and d and g",
"A_E_F": "a and e and f",
"A_E_G": "a and e and g"
}


I had a look at the documentation for itertools but I was not able to understand how I can achieve the desired output.










share|improve this question





























    8















    Assuming that I have 3 different dictionaries:



    dict1 = {
    "A": "a"
    }

    dict2 = {
    "B": "b",
    "C": "c",
    "D": "d",
    "E": "e"
    }

    dict3 = {
    "F": "f",
    "G": "g"
    }


    I want to compute the product of these dictionaries (excluding the product between dict2 and dict3) and combine both the keys and values where the keys are concatenated with _ and values with ' and '



    The desired output would be a single dictionary:



    {
    # dict1 x dict2
    "A_B": "a and b",
    "A_C": "a and c",
    "A_D": "a and d",
    "A_E": "a and e",

    # dict1 x dict3
    "A_F": "a and f",
    "A_G": "a and g",

    # dict1 x dict2 x dict3
    "A_B_F": "a and b and f",
    "A_B_G": "a and b and g",
    "A_C_F": "a and c and f",
    "A_C_G": "a and c and g",
    "A_D_F": "a and d and f",
    "A_D_G": "a and d and g",
    "A_E_F": "a and e and f",
    "A_E_G": "a and e and g"
    }


    I had a look at the documentation for itertools but I was not able to understand how I can achieve the desired output.










    share|improve this question

























      8












      8








      8


      1






      Assuming that I have 3 different dictionaries:



      dict1 = {
      "A": "a"
      }

      dict2 = {
      "B": "b",
      "C": "c",
      "D": "d",
      "E": "e"
      }

      dict3 = {
      "F": "f",
      "G": "g"
      }


      I want to compute the product of these dictionaries (excluding the product between dict2 and dict3) and combine both the keys and values where the keys are concatenated with _ and values with ' and '



      The desired output would be a single dictionary:



      {
      # dict1 x dict2
      "A_B": "a and b",
      "A_C": "a and c",
      "A_D": "a and d",
      "A_E": "a and e",

      # dict1 x dict3
      "A_F": "a and f",
      "A_G": "a and g",

      # dict1 x dict2 x dict3
      "A_B_F": "a and b and f",
      "A_B_G": "a and b and g",
      "A_C_F": "a and c and f",
      "A_C_G": "a and c and g",
      "A_D_F": "a and d and f",
      "A_D_G": "a and d and g",
      "A_E_F": "a and e and f",
      "A_E_G": "a and e and g"
      }


      I had a look at the documentation for itertools but I was not able to understand how I can achieve the desired output.










      share|improve this question














      Assuming that I have 3 different dictionaries:



      dict1 = {
      "A": "a"
      }

      dict2 = {
      "B": "b",
      "C": "c",
      "D": "d",
      "E": "e"
      }

      dict3 = {
      "F": "f",
      "G": "g"
      }


      I want to compute the product of these dictionaries (excluding the product between dict2 and dict3) and combine both the keys and values where the keys are concatenated with _ and values with ' and '



      The desired output would be a single dictionary:



      {
      # dict1 x dict2
      "A_B": "a and b",
      "A_C": "a and c",
      "A_D": "a and d",
      "A_E": "a and e",

      # dict1 x dict3
      "A_F": "a and f",
      "A_G": "a and g",

      # dict1 x dict2 x dict3
      "A_B_F": "a and b and f",
      "A_B_G": "a and b and g",
      "A_C_F": "a and c and f",
      "A_C_G": "a and c and g",
      "A_D_F": "a and d and f",
      "A_D_G": "a and d and g",
      "A_E_F": "a and e and f",
      "A_E_G": "a and e and g"
      }


      I had a look at the documentation for itertools but I was not able to understand how I can achieve the desired output.







      python






      share|improve this question













      share|improve this question











      share|improve this question




      share|improve this question










      asked yesterday









      Old-SchoolOld-School

      676




      676
























          4 Answers
          4






          active

          oldest

          votes


















          7














          The function that will do the job is itertools.product.
          First, here is how you can print out the product dict1 x dict2 x dict3:



          for t in product(dict1.items(), dict2.items(), dict3.items()): 
          k, v = zip(*t)
          print("_".join(k), "-", " and ".join(v))


          Output:



          A_B_F - a and b and f
          A_B_G - a and b and g
          A_C_F - a and c and f
          A_C_G - a and c and g
          A_D_F - a and d and f
          A_D_G - a and d and g
          A_E_F - a and e and f
          A_E_G - a and e and g


          Now, just populate a result dictionary:



          result = {}
          for t in product(dict1.items(), dict2.items(), dict3.items()):
          k, v = zip(*t)
          result["_".join(k)] = " and ".join(v)


          You can now add to this dictionary the dict1 x dict2 and dict1 x dict3 products, that are even simpler to compute.





          Based on @ShadowRanger's comment, here is a complete snippet:



          import itertools
          import pprint


          dict1 = {
          "A": "a"
          }

          dict2 = {
          "B": "b",
          "C": "c",
          "D": "d",
          "E": "e"
          }

          dict3 = {
          "F": "f",
          "G": "g"
          }


          result = {}
          for dicts in ((dict1, dict2), (dict1, dict3), (dict1, dict2, dict3)):
          for t in itertools.product(*(d.items() for d in dicts)):
          k, v = zip(*t)
          result["_".join(k)] = " and ".join(v)

          pprint.pprint(result)


          Output:



          {'A_B': 'a and b',
          'A_B_F': 'a and b and f',
          'A_B_G': 'a and b and g',
          'A_C': 'a and c',
          'A_C_F': 'a and c and f',
          'A_C_G': 'a and c and g',
          'A_D': 'a and d',
          'A_D_F': 'a and d and f',
          'A_D_G': 'a and d and g',
          'A_E': 'a and e',
          'A_E_F': 'a and e and f',
          'A_E_G': 'a and e and g',
          'A_F': 'a and f',
          'A_G': 'a and g'}





          share|improve this answer





















          • 1





            is functools supposed to be itertools?

            – Ben Jones
            yesterday








          • 1





            @BenJones Yeah sure my bad, I always mix them up...

            – Right leg
            yesterday











          • No worries. Now I know about functools!

            – Ben Jones
            yesterday






          • 1





            @BenJones Wanna learn about some more magic? Check out more_itertools :)

            – Right leg
            yesterday











          • Adding an outer loop of for dicts in ((dict1, dict2), (dict1, dict3), (dict1, dict2, dict3)): and making the inner loop for t in product(*[d.items() for d in dicts]): would let you produce the result with minimal code repetition.

            – ShadowRanger
            yesterday



















          1














          To produce all pairings, you can use two recursive generator functions: one to find the overall combinations of dictionaries, and the other to pair the keys and values:



          def pair_dicts(data, c):
          if not data:
          keys, values = zip(*c)
          yield ('_'.join(keys), ' and '.join(values))
          else:
          for i in data[0]:
          yield from pair_dicts(data[1:], c+[i])

          def combos(d, c = ):
          if len(c) == len(d):
          yield c
          else:
          if len(c) > 1:
          yield c
          for i in d:
          if all(h != i for h in c):
          yield from combos(d, c+[i])

          new_d = [[list(c.items()) for c in i] for i in combos([dict1, dict2, dict3])]
          final_result = dict(i for b in new_d for i in pair_dicts(b, ))


          Output:



          {'A_B': 'a and b', 'A_C': 'a and c', 'A_D': 'a and d', 'A_E': 'a and e', 'A_B_F': 'a and b and f', 'A_B_G': 'a and b and g', 'A_C_F': 'a and c and f', 'A_C_G': 'a and c and g', 'A_D_F': 'a and d and f', 'A_D_G': 'a and d and g', 'A_E_F': 'a and e and f', 'A_E_G': 'a and e and g', 'A_F': 'a and f', 'A_G': 'a and g', 'A_F_B': 'a and f and b', 'A_F_C': 'a and f and c', 'A_F_D': 'a and f and d', 'A_F_E': 'a and f and e', 'A_G_B': 'a and g and b', 'A_G_C': 'a and g and c', 'A_G_D': 'a and g and d', 'A_G_E': 'a and g and e', 'B_A': 'b and a', 'C_A': 'c and a', 'D_A': 'd and a', 'E_A': 'e and a', 'B_A_F': 'b and a and f', 'B_A_G': 'b and a and g', 'C_A_F': 'c and a and f', 'C_A_G': 'c and a and g', 'D_A_F': 'd and a and f', 'D_A_G': 'd and a and g', 'E_A_F': 'e and a and f', 'E_A_G': 'e and a and g', 'B_F': 'b and f', 'B_G': 'b and g', 'C_F': 'c and f', 'C_G': 'c and g', 'D_F': 'd and f', 'D_G': 'd and g', 'E_F': 'e and f', 'E_G': 'e and g', 'B_F_A': 'b and f and a', 'B_G_A': 'b and g and a', 'C_F_A': 'c and f and a', 'C_G_A': 'c and g and a', 'D_F_A': 'd and f and a', 'D_G_A': 'd and g and a', 'E_F_A': 'e and f and a', 'E_G_A': 'e and g and a', 'F_A': 'f and a', 'G_A': 'g and a', 'F_A_B': 'f and a and b', 'F_A_C': 'f and a and c', 'F_A_D': 'f and a and d', 'F_A_E': 'f and a and e', 'G_A_B': 'g and a and b', 'G_A_C': 'g and a and c', 'G_A_D': 'g and a and d', 'G_A_E': 'g and a and e', 'F_B': 'f and b', 'F_C': 'f and c', 'F_D': 'f and d', 'F_E': 'f and e', 'G_B': 'g and b', 'G_C': 'g and c', 'G_D': 'g and d', 'G_E': 'g and e', 'F_B_A': 'f and b and a', 'F_C_A': 'f and c and a', 'F_D_A': 'f and d and a', 'F_E_A': 'f and e and a', 'G_B_A': 'g and b and a', 'G_C_A': 'g and c and a', 'G_D_A': 'g and d and a', 'G_E_A': 'g and e and a'}





          share|improve this answer
























          • Although it's not an issue here, I'd generally advise against using a list or any other mutable value as a default value, and would rather go for def combos(d, c=None): if c is None: c = . See stackoverflow.com/questions/1132941/…

            – Right leg
            yesterday



















          0














          I created a (not so nice) function to do your task with arbitrary number of dictionaries.



          (Explanation below)



          import itertools as it

          dict1 = {
          "A": "a"
          }

          dict2 = {
          "B": "b",
          "C": "c",
          "D": "d",
          "E": "e"
          }

          dict3 = {
          "F": "f",
          "G": "g"
          }



          def custom_dict_product(dictionaries):
          return dict(zip(map("_".join, it.product(*map(dict.keys, dictionaries))),
          map(" and ".join, it.product(*map(dict.values, dictionaries)))))

          result = custom_dict_product([dict1,dict2])
          result.update(custom_dict_product([dict1,dict3]))
          result.update(custom_dict_product([dict1,dict2,dict3]))
          result
          #{'A_B': 'a and b',
          # 'A_B_F': 'a and b and f',
          # 'A_B_G': 'a and b and g',
          # 'A_C': 'a and c',
          # 'A_C_F': 'a and c and f',
          # 'A_C_G': 'a and c and g',
          # 'A_D': 'a and d',
          # 'A_D_F': 'a and d and f',
          # 'A_D_G': 'a and d and g',
          # 'A_E': 'a and e',
          # 'A_E_F': 'a and e and f',
          # 'A_E_G': 'a and e and g',
          # 'A_F': 'a and f',
          # 'A_G': 'a and g'}


          The function takes the given dictionaries and gets their keys and values, which is done by map(dict.keys, dictionaries))and map(dict.values, dictionaries)). The results of the first call



          list(it.product(*map(dict.keys, [dict1,dict2])))
          # [('A', 'C'), ('A', 'E'), ('A', 'B'), ('A', 'D')]


          The tuples insides this list are then forced to your desired structure with join(and again an map call to do this for every element):



          "_".join(('A', 'C'))
          # 'A_C'
          list(map("_".join, it.product(*map(dict.keys, [dict1,dict2]))))
          # ['A_C', 'A_E', 'A_B', 'A_D']


          Finally the two resulting lists are transformed to tuples of (keys, values) with the call of zip and handed to the dictionary creation.






          share|improve this answer










          New contributor




          Sparky05 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
          Check out our Code of Conduct.




























            0














            Here a dirty, but working, solution that makes use of itertools



            from itertools import product, combinations


            # create a list and sum dict to be used later
            t = [dict1, dict2, dict3]
            k = {}
            for d in t:
            k.update(d)


            # iterate over "i" order of combinations ("dict1_X" or "dict1_X_Y") and
            # the cartesian product of keys for each combination

            results = {}
            for i in range(2, 4):
            a = [
            [
            results.update({"_".join(y): " and ".join([k[j] for j in y])})
            for y in product(*x)
            ]
            for x in combinations(t, i)
            if dict1 in x
            ]

            results


            Output:



            {'A_B': 'a and b',
            'A_B_F': 'a and b and f',
            'A_B_G': 'a and b and g',
            'A_C': 'a and c',
            'A_C_F': 'a and c and f',
            'A_C_G': 'a and c and g',
            'A_D': 'a and d',
            'A_D_F': 'a and d and f',
            'A_D_G': 'a and d and g',
            'A_E': 'a and e',
            'A_E_F': 'a and e and f',
            'A_E_G': 'a and e and g',
            'A_F': 'a and f',
            'A_G': 'a and g'}





            share|improve this answer










            New contributor




            Lante Dellarovere is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
            Check out our Code of Conduct.





















              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%2f55636895%2fcompute-the-product-of-3-dictionaries-and-concatenate-keys-and-values%23new-answer', 'question_page');
              }
              );

              Post as a guest















              Required, but never shown

























              4 Answers
              4






              active

              oldest

              votes








              4 Answers
              4






              active

              oldest

              votes









              active

              oldest

              votes






              active

              oldest

              votes









              7














              The function that will do the job is itertools.product.
              First, here is how you can print out the product dict1 x dict2 x dict3:



              for t in product(dict1.items(), dict2.items(), dict3.items()): 
              k, v = zip(*t)
              print("_".join(k), "-", " and ".join(v))


              Output:



              A_B_F - a and b and f
              A_B_G - a and b and g
              A_C_F - a and c and f
              A_C_G - a and c and g
              A_D_F - a and d and f
              A_D_G - a and d and g
              A_E_F - a and e and f
              A_E_G - a and e and g


              Now, just populate a result dictionary:



              result = {}
              for t in product(dict1.items(), dict2.items(), dict3.items()):
              k, v = zip(*t)
              result["_".join(k)] = " and ".join(v)


              You can now add to this dictionary the dict1 x dict2 and dict1 x dict3 products, that are even simpler to compute.





              Based on @ShadowRanger's comment, here is a complete snippet:



              import itertools
              import pprint


              dict1 = {
              "A": "a"
              }

              dict2 = {
              "B": "b",
              "C": "c",
              "D": "d",
              "E": "e"
              }

              dict3 = {
              "F": "f",
              "G": "g"
              }


              result = {}
              for dicts in ((dict1, dict2), (dict1, dict3), (dict1, dict2, dict3)):
              for t in itertools.product(*(d.items() for d in dicts)):
              k, v = zip(*t)
              result["_".join(k)] = " and ".join(v)

              pprint.pprint(result)


              Output:



              {'A_B': 'a and b',
              'A_B_F': 'a and b and f',
              'A_B_G': 'a and b and g',
              'A_C': 'a and c',
              'A_C_F': 'a and c and f',
              'A_C_G': 'a and c and g',
              'A_D': 'a and d',
              'A_D_F': 'a and d and f',
              'A_D_G': 'a and d and g',
              'A_E': 'a and e',
              'A_E_F': 'a and e and f',
              'A_E_G': 'a and e and g',
              'A_F': 'a and f',
              'A_G': 'a and g'}





              share|improve this answer





















              • 1





                is functools supposed to be itertools?

                – Ben Jones
                yesterday








              • 1





                @BenJones Yeah sure my bad, I always mix them up...

                – Right leg
                yesterday











              • No worries. Now I know about functools!

                – Ben Jones
                yesterday






              • 1





                @BenJones Wanna learn about some more magic? Check out more_itertools :)

                – Right leg
                yesterday











              • Adding an outer loop of for dicts in ((dict1, dict2), (dict1, dict3), (dict1, dict2, dict3)): and making the inner loop for t in product(*[d.items() for d in dicts]): would let you produce the result with minimal code repetition.

                – ShadowRanger
                yesterday
















              7














              The function that will do the job is itertools.product.
              First, here is how you can print out the product dict1 x dict2 x dict3:



              for t in product(dict1.items(), dict2.items(), dict3.items()): 
              k, v = zip(*t)
              print("_".join(k), "-", " and ".join(v))


              Output:



              A_B_F - a and b and f
              A_B_G - a and b and g
              A_C_F - a and c and f
              A_C_G - a and c and g
              A_D_F - a and d and f
              A_D_G - a and d and g
              A_E_F - a and e and f
              A_E_G - a and e and g


              Now, just populate a result dictionary:



              result = {}
              for t in product(dict1.items(), dict2.items(), dict3.items()):
              k, v = zip(*t)
              result["_".join(k)] = " and ".join(v)


              You can now add to this dictionary the dict1 x dict2 and dict1 x dict3 products, that are even simpler to compute.





              Based on @ShadowRanger's comment, here is a complete snippet:



              import itertools
              import pprint


              dict1 = {
              "A": "a"
              }

              dict2 = {
              "B": "b",
              "C": "c",
              "D": "d",
              "E": "e"
              }

              dict3 = {
              "F": "f",
              "G": "g"
              }


              result = {}
              for dicts in ((dict1, dict2), (dict1, dict3), (dict1, dict2, dict3)):
              for t in itertools.product(*(d.items() for d in dicts)):
              k, v = zip(*t)
              result["_".join(k)] = " and ".join(v)

              pprint.pprint(result)


              Output:



              {'A_B': 'a and b',
              'A_B_F': 'a and b and f',
              'A_B_G': 'a and b and g',
              'A_C': 'a and c',
              'A_C_F': 'a and c and f',
              'A_C_G': 'a and c and g',
              'A_D': 'a and d',
              'A_D_F': 'a and d and f',
              'A_D_G': 'a and d and g',
              'A_E': 'a and e',
              'A_E_F': 'a and e and f',
              'A_E_G': 'a and e and g',
              'A_F': 'a and f',
              'A_G': 'a and g'}





              share|improve this answer





















              • 1





                is functools supposed to be itertools?

                – Ben Jones
                yesterday








              • 1





                @BenJones Yeah sure my bad, I always mix them up...

                – Right leg
                yesterday











              • No worries. Now I know about functools!

                – Ben Jones
                yesterday






              • 1





                @BenJones Wanna learn about some more magic? Check out more_itertools :)

                – Right leg
                yesterday











              • Adding an outer loop of for dicts in ((dict1, dict2), (dict1, dict3), (dict1, dict2, dict3)): and making the inner loop for t in product(*[d.items() for d in dicts]): would let you produce the result with minimal code repetition.

                – ShadowRanger
                yesterday














              7












              7








              7







              The function that will do the job is itertools.product.
              First, here is how you can print out the product dict1 x dict2 x dict3:



              for t in product(dict1.items(), dict2.items(), dict3.items()): 
              k, v = zip(*t)
              print("_".join(k), "-", " and ".join(v))


              Output:



              A_B_F - a and b and f
              A_B_G - a and b and g
              A_C_F - a and c and f
              A_C_G - a and c and g
              A_D_F - a and d and f
              A_D_G - a and d and g
              A_E_F - a and e and f
              A_E_G - a and e and g


              Now, just populate a result dictionary:



              result = {}
              for t in product(dict1.items(), dict2.items(), dict3.items()):
              k, v = zip(*t)
              result["_".join(k)] = " and ".join(v)


              You can now add to this dictionary the dict1 x dict2 and dict1 x dict3 products, that are even simpler to compute.





              Based on @ShadowRanger's comment, here is a complete snippet:



              import itertools
              import pprint


              dict1 = {
              "A": "a"
              }

              dict2 = {
              "B": "b",
              "C": "c",
              "D": "d",
              "E": "e"
              }

              dict3 = {
              "F": "f",
              "G": "g"
              }


              result = {}
              for dicts in ((dict1, dict2), (dict1, dict3), (dict1, dict2, dict3)):
              for t in itertools.product(*(d.items() for d in dicts)):
              k, v = zip(*t)
              result["_".join(k)] = " and ".join(v)

              pprint.pprint(result)


              Output:



              {'A_B': 'a and b',
              'A_B_F': 'a and b and f',
              'A_B_G': 'a and b and g',
              'A_C': 'a and c',
              'A_C_F': 'a and c and f',
              'A_C_G': 'a and c and g',
              'A_D': 'a and d',
              'A_D_F': 'a and d and f',
              'A_D_G': 'a and d and g',
              'A_E': 'a and e',
              'A_E_F': 'a and e and f',
              'A_E_G': 'a and e and g',
              'A_F': 'a and f',
              'A_G': 'a and g'}





              share|improve this answer















              The function that will do the job is itertools.product.
              First, here is how you can print out the product dict1 x dict2 x dict3:



              for t in product(dict1.items(), dict2.items(), dict3.items()): 
              k, v = zip(*t)
              print("_".join(k), "-", " and ".join(v))


              Output:



              A_B_F - a and b and f
              A_B_G - a and b and g
              A_C_F - a and c and f
              A_C_G - a and c and g
              A_D_F - a and d and f
              A_D_G - a and d and g
              A_E_F - a and e and f
              A_E_G - a and e and g


              Now, just populate a result dictionary:



              result = {}
              for t in product(dict1.items(), dict2.items(), dict3.items()):
              k, v = zip(*t)
              result["_".join(k)] = " and ".join(v)


              You can now add to this dictionary the dict1 x dict2 and dict1 x dict3 products, that are even simpler to compute.





              Based on @ShadowRanger's comment, here is a complete snippet:



              import itertools
              import pprint


              dict1 = {
              "A": "a"
              }

              dict2 = {
              "B": "b",
              "C": "c",
              "D": "d",
              "E": "e"
              }

              dict3 = {
              "F": "f",
              "G": "g"
              }


              result = {}
              for dicts in ((dict1, dict2), (dict1, dict3), (dict1, dict2, dict3)):
              for t in itertools.product(*(d.items() for d in dicts)):
              k, v = zip(*t)
              result["_".join(k)] = " and ".join(v)

              pprint.pprint(result)


              Output:



              {'A_B': 'a and b',
              'A_B_F': 'a and b and f',
              'A_B_G': 'a and b and g',
              'A_C': 'a and c',
              'A_C_F': 'a and c and f',
              'A_C_G': 'a and c and g',
              'A_D': 'a and d',
              'A_D_F': 'a and d and f',
              'A_D_G': 'a and d and g',
              'A_E': 'a and e',
              'A_E_F': 'a and e and f',
              'A_E_G': 'a and e and g',
              'A_F': 'a and f',
              'A_G': 'a and g'}






              share|improve this answer














              share|improve this answer



              share|improve this answer








              edited yesterday

























              answered yesterday









              Right legRight leg

              8,55342450




              8,55342450








              • 1





                is functools supposed to be itertools?

                – Ben Jones
                yesterday








              • 1





                @BenJones Yeah sure my bad, I always mix them up...

                – Right leg
                yesterday











              • No worries. Now I know about functools!

                – Ben Jones
                yesterday






              • 1





                @BenJones Wanna learn about some more magic? Check out more_itertools :)

                – Right leg
                yesterday











              • Adding an outer loop of for dicts in ((dict1, dict2), (dict1, dict3), (dict1, dict2, dict3)): and making the inner loop for t in product(*[d.items() for d in dicts]): would let you produce the result with minimal code repetition.

                – ShadowRanger
                yesterday














              • 1





                is functools supposed to be itertools?

                – Ben Jones
                yesterday








              • 1





                @BenJones Yeah sure my bad, I always mix them up...

                – Right leg
                yesterday











              • No worries. Now I know about functools!

                – Ben Jones
                yesterday






              • 1





                @BenJones Wanna learn about some more magic? Check out more_itertools :)

                – Right leg
                yesterday











              • Adding an outer loop of for dicts in ((dict1, dict2), (dict1, dict3), (dict1, dict2, dict3)): and making the inner loop for t in product(*[d.items() for d in dicts]): would let you produce the result with minimal code repetition.

                – ShadowRanger
                yesterday








              1




              1





              is functools supposed to be itertools?

              – Ben Jones
              yesterday







              is functools supposed to be itertools?

              – Ben Jones
              yesterday






              1




              1





              @BenJones Yeah sure my bad, I always mix them up...

              – Right leg
              yesterday





              @BenJones Yeah sure my bad, I always mix them up...

              – Right leg
              yesterday













              No worries. Now I know about functools!

              – Ben Jones
              yesterday





              No worries. Now I know about functools!

              – Ben Jones
              yesterday




              1




              1





              @BenJones Wanna learn about some more magic? Check out more_itertools :)

              – Right leg
              yesterday





              @BenJones Wanna learn about some more magic? Check out more_itertools :)

              – Right leg
              yesterday













              Adding an outer loop of for dicts in ((dict1, dict2), (dict1, dict3), (dict1, dict2, dict3)): and making the inner loop for t in product(*[d.items() for d in dicts]): would let you produce the result with minimal code repetition.

              – ShadowRanger
              yesterday





              Adding an outer loop of for dicts in ((dict1, dict2), (dict1, dict3), (dict1, dict2, dict3)): and making the inner loop for t in product(*[d.items() for d in dicts]): would let you produce the result with minimal code repetition.

              – ShadowRanger
              yesterday













              1














              To produce all pairings, you can use two recursive generator functions: one to find the overall combinations of dictionaries, and the other to pair the keys and values:



              def pair_dicts(data, c):
              if not data:
              keys, values = zip(*c)
              yield ('_'.join(keys), ' and '.join(values))
              else:
              for i in data[0]:
              yield from pair_dicts(data[1:], c+[i])

              def combos(d, c = ):
              if len(c) == len(d):
              yield c
              else:
              if len(c) > 1:
              yield c
              for i in d:
              if all(h != i for h in c):
              yield from combos(d, c+[i])

              new_d = [[list(c.items()) for c in i] for i in combos([dict1, dict2, dict3])]
              final_result = dict(i for b in new_d for i in pair_dicts(b, ))


              Output:



              {'A_B': 'a and b', 'A_C': 'a and c', 'A_D': 'a and d', 'A_E': 'a and e', 'A_B_F': 'a and b and f', 'A_B_G': 'a and b and g', 'A_C_F': 'a and c and f', 'A_C_G': 'a and c and g', 'A_D_F': 'a and d and f', 'A_D_G': 'a and d and g', 'A_E_F': 'a and e and f', 'A_E_G': 'a and e and g', 'A_F': 'a and f', 'A_G': 'a and g', 'A_F_B': 'a and f and b', 'A_F_C': 'a and f and c', 'A_F_D': 'a and f and d', 'A_F_E': 'a and f and e', 'A_G_B': 'a and g and b', 'A_G_C': 'a and g and c', 'A_G_D': 'a and g and d', 'A_G_E': 'a and g and e', 'B_A': 'b and a', 'C_A': 'c and a', 'D_A': 'd and a', 'E_A': 'e and a', 'B_A_F': 'b and a and f', 'B_A_G': 'b and a and g', 'C_A_F': 'c and a and f', 'C_A_G': 'c and a and g', 'D_A_F': 'd and a and f', 'D_A_G': 'd and a and g', 'E_A_F': 'e and a and f', 'E_A_G': 'e and a and g', 'B_F': 'b and f', 'B_G': 'b and g', 'C_F': 'c and f', 'C_G': 'c and g', 'D_F': 'd and f', 'D_G': 'd and g', 'E_F': 'e and f', 'E_G': 'e and g', 'B_F_A': 'b and f and a', 'B_G_A': 'b and g and a', 'C_F_A': 'c and f and a', 'C_G_A': 'c and g and a', 'D_F_A': 'd and f and a', 'D_G_A': 'd and g and a', 'E_F_A': 'e and f and a', 'E_G_A': 'e and g and a', 'F_A': 'f and a', 'G_A': 'g and a', 'F_A_B': 'f and a and b', 'F_A_C': 'f and a and c', 'F_A_D': 'f and a and d', 'F_A_E': 'f and a and e', 'G_A_B': 'g and a and b', 'G_A_C': 'g and a and c', 'G_A_D': 'g and a and d', 'G_A_E': 'g and a and e', 'F_B': 'f and b', 'F_C': 'f and c', 'F_D': 'f and d', 'F_E': 'f and e', 'G_B': 'g and b', 'G_C': 'g and c', 'G_D': 'g and d', 'G_E': 'g and e', 'F_B_A': 'f and b and a', 'F_C_A': 'f and c and a', 'F_D_A': 'f and d and a', 'F_E_A': 'f and e and a', 'G_B_A': 'g and b and a', 'G_C_A': 'g and c and a', 'G_D_A': 'g and d and a', 'G_E_A': 'g and e and a'}





              share|improve this answer
























              • Although it's not an issue here, I'd generally advise against using a list or any other mutable value as a default value, and would rather go for def combos(d, c=None): if c is None: c = . See stackoverflow.com/questions/1132941/…

                – Right leg
                yesterday
















              1














              To produce all pairings, you can use two recursive generator functions: one to find the overall combinations of dictionaries, and the other to pair the keys and values:



              def pair_dicts(data, c):
              if not data:
              keys, values = zip(*c)
              yield ('_'.join(keys), ' and '.join(values))
              else:
              for i in data[0]:
              yield from pair_dicts(data[1:], c+[i])

              def combos(d, c = ):
              if len(c) == len(d):
              yield c
              else:
              if len(c) > 1:
              yield c
              for i in d:
              if all(h != i for h in c):
              yield from combos(d, c+[i])

              new_d = [[list(c.items()) for c in i] for i in combos([dict1, dict2, dict3])]
              final_result = dict(i for b in new_d for i in pair_dicts(b, ))


              Output:



              {'A_B': 'a and b', 'A_C': 'a and c', 'A_D': 'a and d', 'A_E': 'a and e', 'A_B_F': 'a and b and f', 'A_B_G': 'a and b and g', 'A_C_F': 'a and c and f', 'A_C_G': 'a and c and g', 'A_D_F': 'a and d and f', 'A_D_G': 'a and d and g', 'A_E_F': 'a and e and f', 'A_E_G': 'a and e and g', 'A_F': 'a and f', 'A_G': 'a and g', 'A_F_B': 'a and f and b', 'A_F_C': 'a and f and c', 'A_F_D': 'a and f and d', 'A_F_E': 'a and f and e', 'A_G_B': 'a and g and b', 'A_G_C': 'a and g and c', 'A_G_D': 'a and g and d', 'A_G_E': 'a and g and e', 'B_A': 'b and a', 'C_A': 'c and a', 'D_A': 'd and a', 'E_A': 'e and a', 'B_A_F': 'b and a and f', 'B_A_G': 'b and a and g', 'C_A_F': 'c and a and f', 'C_A_G': 'c and a and g', 'D_A_F': 'd and a and f', 'D_A_G': 'd and a and g', 'E_A_F': 'e and a and f', 'E_A_G': 'e and a and g', 'B_F': 'b and f', 'B_G': 'b and g', 'C_F': 'c and f', 'C_G': 'c and g', 'D_F': 'd and f', 'D_G': 'd and g', 'E_F': 'e and f', 'E_G': 'e and g', 'B_F_A': 'b and f and a', 'B_G_A': 'b and g and a', 'C_F_A': 'c and f and a', 'C_G_A': 'c and g and a', 'D_F_A': 'd and f and a', 'D_G_A': 'd and g and a', 'E_F_A': 'e and f and a', 'E_G_A': 'e and g and a', 'F_A': 'f and a', 'G_A': 'g and a', 'F_A_B': 'f and a and b', 'F_A_C': 'f and a and c', 'F_A_D': 'f and a and d', 'F_A_E': 'f and a and e', 'G_A_B': 'g and a and b', 'G_A_C': 'g and a and c', 'G_A_D': 'g and a and d', 'G_A_E': 'g and a and e', 'F_B': 'f and b', 'F_C': 'f and c', 'F_D': 'f and d', 'F_E': 'f and e', 'G_B': 'g and b', 'G_C': 'g and c', 'G_D': 'g and d', 'G_E': 'g and e', 'F_B_A': 'f and b and a', 'F_C_A': 'f and c and a', 'F_D_A': 'f and d and a', 'F_E_A': 'f and e and a', 'G_B_A': 'g and b and a', 'G_C_A': 'g and c and a', 'G_D_A': 'g and d and a', 'G_E_A': 'g and e and a'}





              share|improve this answer
























              • Although it's not an issue here, I'd generally advise against using a list or any other mutable value as a default value, and would rather go for def combos(d, c=None): if c is None: c = . See stackoverflow.com/questions/1132941/…

                – Right leg
                yesterday














              1












              1








              1







              To produce all pairings, you can use two recursive generator functions: one to find the overall combinations of dictionaries, and the other to pair the keys and values:



              def pair_dicts(data, c):
              if not data:
              keys, values = zip(*c)
              yield ('_'.join(keys), ' and '.join(values))
              else:
              for i in data[0]:
              yield from pair_dicts(data[1:], c+[i])

              def combos(d, c = ):
              if len(c) == len(d):
              yield c
              else:
              if len(c) > 1:
              yield c
              for i in d:
              if all(h != i for h in c):
              yield from combos(d, c+[i])

              new_d = [[list(c.items()) for c in i] for i in combos([dict1, dict2, dict3])]
              final_result = dict(i for b in new_d for i in pair_dicts(b, ))


              Output:



              {'A_B': 'a and b', 'A_C': 'a and c', 'A_D': 'a and d', 'A_E': 'a and e', 'A_B_F': 'a and b and f', 'A_B_G': 'a and b and g', 'A_C_F': 'a and c and f', 'A_C_G': 'a and c and g', 'A_D_F': 'a and d and f', 'A_D_G': 'a and d and g', 'A_E_F': 'a and e and f', 'A_E_G': 'a and e and g', 'A_F': 'a and f', 'A_G': 'a and g', 'A_F_B': 'a and f and b', 'A_F_C': 'a and f and c', 'A_F_D': 'a and f and d', 'A_F_E': 'a and f and e', 'A_G_B': 'a and g and b', 'A_G_C': 'a and g and c', 'A_G_D': 'a and g and d', 'A_G_E': 'a and g and e', 'B_A': 'b and a', 'C_A': 'c and a', 'D_A': 'd and a', 'E_A': 'e and a', 'B_A_F': 'b and a and f', 'B_A_G': 'b and a and g', 'C_A_F': 'c and a and f', 'C_A_G': 'c and a and g', 'D_A_F': 'd and a and f', 'D_A_G': 'd and a and g', 'E_A_F': 'e and a and f', 'E_A_G': 'e and a and g', 'B_F': 'b and f', 'B_G': 'b and g', 'C_F': 'c and f', 'C_G': 'c and g', 'D_F': 'd and f', 'D_G': 'd and g', 'E_F': 'e and f', 'E_G': 'e and g', 'B_F_A': 'b and f and a', 'B_G_A': 'b and g and a', 'C_F_A': 'c and f and a', 'C_G_A': 'c and g and a', 'D_F_A': 'd and f and a', 'D_G_A': 'd and g and a', 'E_F_A': 'e and f and a', 'E_G_A': 'e and g and a', 'F_A': 'f and a', 'G_A': 'g and a', 'F_A_B': 'f and a and b', 'F_A_C': 'f and a and c', 'F_A_D': 'f and a and d', 'F_A_E': 'f and a and e', 'G_A_B': 'g and a and b', 'G_A_C': 'g and a and c', 'G_A_D': 'g and a and d', 'G_A_E': 'g and a and e', 'F_B': 'f and b', 'F_C': 'f and c', 'F_D': 'f and d', 'F_E': 'f and e', 'G_B': 'g and b', 'G_C': 'g and c', 'G_D': 'g and d', 'G_E': 'g and e', 'F_B_A': 'f and b and a', 'F_C_A': 'f and c and a', 'F_D_A': 'f and d and a', 'F_E_A': 'f and e and a', 'G_B_A': 'g and b and a', 'G_C_A': 'g and c and a', 'G_D_A': 'g and d and a', 'G_E_A': 'g and e and a'}





              share|improve this answer













              To produce all pairings, you can use two recursive generator functions: one to find the overall combinations of dictionaries, and the other to pair the keys and values:



              def pair_dicts(data, c):
              if not data:
              keys, values = zip(*c)
              yield ('_'.join(keys), ' and '.join(values))
              else:
              for i in data[0]:
              yield from pair_dicts(data[1:], c+[i])

              def combos(d, c = ):
              if len(c) == len(d):
              yield c
              else:
              if len(c) > 1:
              yield c
              for i in d:
              if all(h != i for h in c):
              yield from combos(d, c+[i])

              new_d = [[list(c.items()) for c in i] for i in combos([dict1, dict2, dict3])]
              final_result = dict(i for b in new_d for i in pair_dicts(b, ))


              Output:



              {'A_B': 'a and b', 'A_C': 'a and c', 'A_D': 'a and d', 'A_E': 'a and e', 'A_B_F': 'a and b and f', 'A_B_G': 'a and b and g', 'A_C_F': 'a and c and f', 'A_C_G': 'a and c and g', 'A_D_F': 'a and d and f', 'A_D_G': 'a and d and g', 'A_E_F': 'a and e and f', 'A_E_G': 'a and e and g', 'A_F': 'a and f', 'A_G': 'a and g', 'A_F_B': 'a and f and b', 'A_F_C': 'a and f and c', 'A_F_D': 'a and f and d', 'A_F_E': 'a and f and e', 'A_G_B': 'a and g and b', 'A_G_C': 'a and g and c', 'A_G_D': 'a and g and d', 'A_G_E': 'a and g and e', 'B_A': 'b and a', 'C_A': 'c and a', 'D_A': 'd and a', 'E_A': 'e and a', 'B_A_F': 'b and a and f', 'B_A_G': 'b and a and g', 'C_A_F': 'c and a and f', 'C_A_G': 'c and a and g', 'D_A_F': 'd and a and f', 'D_A_G': 'd and a and g', 'E_A_F': 'e and a and f', 'E_A_G': 'e and a and g', 'B_F': 'b and f', 'B_G': 'b and g', 'C_F': 'c and f', 'C_G': 'c and g', 'D_F': 'd and f', 'D_G': 'd and g', 'E_F': 'e and f', 'E_G': 'e and g', 'B_F_A': 'b and f and a', 'B_G_A': 'b and g and a', 'C_F_A': 'c and f and a', 'C_G_A': 'c and g and a', 'D_F_A': 'd and f and a', 'D_G_A': 'd and g and a', 'E_F_A': 'e and f and a', 'E_G_A': 'e and g and a', 'F_A': 'f and a', 'G_A': 'g and a', 'F_A_B': 'f and a and b', 'F_A_C': 'f and a and c', 'F_A_D': 'f and a and d', 'F_A_E': 'f and a and e', 'G_A_B': 'g and a and b', 'G_A_C': 'g and a and c', 'G_A_D': 'g and a and d', 'G_A_E': 'g and a and e', 'F_B': 'f and b', 'F_C': 'f and c', 'F_D': 'f and d', 'F_E': 'f and e', 'G_B': 'g and b', 'G_C': 'g and c', 'G_D': 'g and d', 'G_E': 'g and e', 'F_B_A': 'f and b and a', 'F_C_A': 'f and c and a', 'F_D_A': 'f and d and a', 'F_E_A': 'f and e and a', 'G_B_A': 'g and b and a', 'G_C_A': 'g and c and a', 'G_D_A': 'g and d and a', 'G_E_A': 'g and e and a'}






              share|improve this answer












              share|improve this answer



              share|improve this answer










              answered yesterday









              Ajax1234Ajax1234

              43.1k42954




              43.1k42954













              • Although it's not an issue here, I'd generally advise against using a list or any other mutable value as a default value, and would rather go for def combos(d, c=None): if c is None: c = . See stackoverflow.com/questions/1132941/…

                – Right leg
                yesterday



















              • Although it's not an issue here, I'd generally advise against using a list or any other mutable value as a default value, and would rather go for def combos(d, c=None): if c is None: c = . See stackoverflow.com/questions/1132941/…

                – Right leg
                yesterday

















              Although it's not an issue here, I'd generally advise against using a list or any other mutable value as a default value, and would rather go for def combos(d, c=None): if c is None: c = . See stackoverflow.com/questions/1132941/…

              – Right leg
              yesterday





              Although it's not an issue here, I'd generally advise against using a list or any other mutable value as a default value, and would rather go for def combos(d, c=None): if c is None: c = . See stackoverflow.com/questions/1132941/…

              – Right leg
              yesterday











              0














              I created a (not so nice) function to do your task with arbitrary number of dictionaries.



              (Explanation below)



              import itertools as it

              dict1 = {
              "A": "a"
              }

              dict2 = {
              "B": "b",
              "C": "c",
              "D": "d",
              "E": "e"
              }

              dict3 = {
              "F": "f",
              "G": "g"
              }



              def custom_dict_product(dictionaries):
              return dict(zip(map("_".join, it.product(*map(dict.keys, dictionaries))),
              map(" and ".join, it.product(*map(dict.values, dictionaries)))))

              result = custom_dict_product([dict1,dict2])
              result.update(custom_dict_product([dict1,dict3]))
              result.update(custom_dict_product([dict1,dict2,dict3]))
              result
              #{'A_B': 'a and b',
              # 'A_B_F': 'a and b and f',
              # 'A_B_G': 'a and b and g',
              # 'A_C': 'a and c',
              # 'A_C_F': 'a and c and f',
              # 'A_C_G': 'a and c and g',
              # 'A_D': 'a and d',
              # 'A_D_F': 'a and d and f',
              # 'A_D_G': 'a and d and g',
              # 'A_E': 'a and e',
              # 'A_E_F': 'a and e and f',
              # 'A_E_G': 'a and e and g',
              # 'A_F': 'a and f',
              # 'A_G': 'a and g'}


              The function takes the given dictionaries and gets their keys and values, which is done by map(dict.keys, dictionaries))and map(dict.values, dictionaries)). The results of the first call



              list(it.product(*map(dict.keys, [dict1,dict2])))
              # [('A', 'C'), ('A', 'E'), ('A', 'B'), ('A', 'D')]


              The tuples insides this list are then forced to your desired structure with join(and again an map call to do this for every element):



              "_".join(('A', 'C'))
              # 'A_C'
              list(map("_".join, it.product(*map(dict.keys, [dict1,dict2]))))
              # ['A_C', 'A_E', 'A_B', 'A_D']


              Finally the two resulting lists are transformed to tuples of (keys, values) with the call of zip and handed to the dictionary creation.






              share|improve this answer










              New contributor




              Sparky05 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
              Check out our Code of Conduct.

























                0














                I created a (not so nice) function to do your task with arbitrary number of dictionaries.



                (Explanation below)



                import itertools as it

                dict1 = {
                "A": "a"
                }

                dict2 = {
                "B": "b",
                "C": "c",
                "D": "d",
                "E": "e"
                }

                dict3 = {
                "F": "f",
                "G": "g"
                }



                def custom_dict_product(dictionaries):
                return dict(zip(map("_".join, it.product(*map(dict.keys, dictionaries))),
                map(" and ".join, it.product(*map(dict.values, dictionaries)))))

                result = custom_dict_product([dict1,dict2])
                result.update(custom_dict_product([dict1,dict3]))
                result.update(custom_dict_product([dict1,dict2,dict3]))
                result
                #{'A_B': 'a and b',
                # 'A_B_F': 'a and b and f',
                # 'A_B_G': 'a and b and g',
                # 'A_C': 'a and c',
                # 'A_C_F': 'a and c and f',
                # 'A_C_G': 'a and c and g',
                # 'A_D': 'a and d',
                # 'A_D_F': 'a and d and f',
                # 'A_D_G': 'a and d and g',
                # 'A_E': 'a and e',
                # 'A_E_F': 'a and e and f',
                # 'A_E_G': 'a and e and g',
                # 'A_F': 'a and f',
                # 'A_G': 'a and g'}


                The function takes the given dictionaries and gets their keys and values, which is done by map(dict.keys, dictionaries))and map(dict.values, dictionaries)). The results of the first call



                list(it.product(*map(dict.keys, [dict1,dict2])))
                # [('A', 'C'), ('A', 'E'), ('A', 'B'), ('A', 'D')]


                The tuples insides this list are then forced to your desired structure with join(and again an map call to do this for every element):



                "_".join(('A', 'C'))
                # 'A_C'
                list(map("_".join, it.product(*map(dict.keys, [dict1,dict2]))))
                # ['A_C', 'A_E', 'A_B', 'A_D']


                Finally the two resulting lists are transformed to tuples of (keys, values) with the call of zip and handed to the dictionary creation.






                share|improve this answer










                New contributor




                Sparky05 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
                Check out our Code of Conduct.























                  0












                  0








                  0







                  I created a (not so nice) function to do your task with arbitrary number of dictionaries.



                  (Explanation below)



                  import itertools as it

                  dict1 = {
                  "A": "a"
                  }

                  dict2 = {
                  "B": "b",
                  "C": "c",
                  "D": "d",
                  "E": "e"
                  }

                  dict3 = {
                  "F": "f",
                  "G": "g"
                  }



                  def custom_dict_product(dictionaries):
                  return dict(zip(map("_".join, it.product(*map(dict.keys, dictionaries))),
                  map(" and ".join, it.product(*map(dict.values, dictionaries)))))

                  result = custom_dict_product([dict1,dict2])
                  result.update(custom_dict_product([dict1,dict3]))
                  result.update(custom_dict_product([dict1,dict2,dict3]))
                  result
                  #{'A_B': 'a and b',
                  # 'A_B_F': 'a and b and f',
                  # 'A_B_G': 'a and b and g',
                  # 'A_C': 'a and c',
                  # 'A_C_F': 'a and c and f',
                  # 'A_C_G': 'a and c and g',
                  # 'A_D': 'a and d',
                  # 'A_D_F': 'a and d and f',
                  # 'A_D_G': 'a and d and g',
                  # 'A_E': 'a and e',
                  # 'A_E_F': 'a and e and f',
                  # 'A_E_G': 'a and e and g',
                  # 'A_F': 'a and f',
                  # 'A_G': 'a and g'}


                  The function takes the given dictionaries and gets their keys and values, which is done by map(dict.keys, dictionaries))and map(dict.values, dictionaries)). The results of the first call



                  list(it.product(*map(dict.keys, [dict1,dict2])))
                  # [('A', 'C'), ('A', 'E'), ('A', 'B'), ('A', 'D')]


                  The tuples insides this list are then forced to your desired structure with join(and again an map call to do this for every element):



                  "_".join(('A', 'C'))
                  # 'A_C'
                  list(map("_".join, it.product(*map(dict.keys, [dict1,dict2]))))
                  # ['A_C', 'A_E', 'A_B', 'A_D']


                  Finally the two resulting lists are transformed to tuples of (keys, values) with the call of zip and handed to the dictionary creation.






                  share|improve this answer










                  New contributor




                  Sparky05 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
                  Check out our Code of Conduct.










                  I created a (not so nice) function to do your task with arbitrary number of dictionaries.



                  (Explanation below)



                  import itertools as it

                  dict1 = {
                  "A": "a"
                  }

                  dict2 = {
                  "B": "b",
                  "C": "c",
                  "D": "d",
                  "E": "e"
                  }

                  dict3 = {
                  "F": "f",
                  "G": "g"
                  }



                  def custom_dict_product(dictionaries):
                  return dict(zip(map("_".join, it.product(*map(dict.keys, dictionaries))),
                  map(" and ".join, it.product(*map(dict.values, dictionaries)))))

                  result = custom_dict_product([dict1,dict2])
                  result.update(custom_dict_product([dict1,dict3]))
                  result.update(custom_dict_product([dict1,dict2,dict3]))
                  result
                  #{'A_B': 'a and b',
                  # 'A_B_F': 'a and b and f',
                  # 'A_B_G': 'a and b and g',
                  # 'A_C': 'a and c',
                  # 'A_C_F': 'a and c and f',
                  # 'A_C_G': 'a and c and g',
                  # 'A_D': 'a and d',
                  # 'A_D_F': 'a and d and f',
                  # 'A_D_G': 'a and d and g',
                  # 'A_E': 'a and e',
                  # 'A_E_F': 'a and e and f',
                  # 'A_E_G': 'a and e and g',
                  # 'A_F': 'a and f',
                  # 'A_G': 'a and g'}


                  The function takes the given dictionaries and gets their keys and values, which is done by map(dict.keys, dictionaries))and map(dict.values, dictionaries)). The results of the first call



                  list(it.product(*map(dict.keys, [dict1,dict2])))
                  # [('A', 'C'), ('A', 'E'), ('A', 'B'), ('A', 'D')]


                  The tuples insides this list are then forced to your desired structure with join(and again an map call to do this for every element):



                  "_".join(('A', 'C'))
                  # 'A_C'
                  list(map("_".join, it.product(*map(dict.keys, [dict1,dict2]))))
                  # ['A_C', 'A_E', 'A_B', 'A_D']


                  Finally the two resulting lists are transformed to tuples of (keys, values) with the call of zip and handed to the dictionary creation.







                  share|improve this answer










                  New contributor




                  Sparky05 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
                  Check out our Code of Conduct.









                  share|improve this answer



                  share|improve this answer








                  edited yesterday





















                  New contributor




                  Sparky05 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
                  Check out our Code of Conduct.









                  answered yesterday









                  Sparky05Sparky05

                  1806




                  1806




                  New contributor




                  Sparky05 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
                  Check out our Code of Conduct.





                  New contributor





                  Sparky05 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
                  Check out our Code of Conduct.






                  Sparky05 is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
                  Check out our Code of Conduct.























                      0














                      Here a dirty, but working, solution that makes use of itertools



                      from itertools import product, combinations


                      # create a list and sum dict to be used later
                      t = [dict1, dict2, dict3]
                      k = {}
                      for d in t:
                      k.update(d)


                      # iterate over "i" order of combinations ("dict1_X" or "dict1_X_Y") and
                      # the cartesian product of keys for each combination

                      results = {}
                      for i in range(2, 4):
                      a = [
                      [
                      results.update({"_".join(y): " and ".join([k[j] for j in y])})
                      for y in product(*x)
                      ]
                      for x in combinations(t, i)
                      if dict1 in x
                      ]

                      results


                      Output:



                      {'A_B': 'a and b',
                      'A_B_F': 'a and b and f',
                      'A_B_G': 'a and b and g',
                      'A_C': 'a and c',
                      'A_C_F': 'a and c and f',
                      'A_C_G': 'a and c and g',
                      'A_D': 'a and d',
                      'A_D_F': 'a and d and f',
                      'A_D_G': 'a and d and g',
                      'A_E': 'a and e',
                      'A_E_F': 'a and e and f',
                      'A_E_G': 'a and e and g',
                      'A_F': 'a and f',
                      'A_G': 'a and g'}





                      share|improve this answer










                      New contributor




                      Lante Dellarovere is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
                      Check out our Code of Conduct.

























                        0














                        Here a dirty, but working, solution that makes use of itertools



                        from itertools import product, combinations


                        # create a list and sum dict to be used later
                        t = [dict1, dict2, dict3]
                        k = {}
                        for d in t:
                        k.update(d)


                        # iterate over "i" order of combinations ("dict1_X" or "dict1_X_Y") and
                        # the cartesian product of keys for each combination

                        results = {}
                        for i in range(2, 4):
                        a = [
                        [
                        results.update({"_".join(y): " and ".join([k[j] for j in y])})
                        for y in product(*x)
                        ]
                        for x in combinations(t, i)
                        if dict1 in x
                        ]

                        results


                        Output:



                        {'A_B': 'a and b',
                        'A_B_F': 'a and b and f',
                        'A_B_G': 'a and b and g',
                        'A_C': 'a and c',
                        'A_C_F': 'a and c and f',
                        'A_C_G': 'a and c and g',
                        'A_D': 'a and d',
                        'A_D_F': 'a and d and f',
                        'A_D_G': 'a and d and g',
                        'A_E': 'a and e',
                        'A_E_F': 'a and e and f',
                        'A_E_G': 'a and e and g',
                        'A_F': 'a and f',
                        'A_G': 'a and g'}





                        share|improve this answer










                        New contributor




                        Lante Dellarovere is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
                        Check out our Code of Conduct.























                          0












                          0








                          0







                          Here a dirty, but working, solution that makes use of itertools



                          from itertools import product, combinations


                          # create a list and sum dict to be used later
                          t = [dict1, dict2, dict3]
                          k = {}
                          for d in t:
                          k.update(d)


                          # iterate over "i" order of combinations ("dict1_X" or "dict1_X_Y") and
                          # the cartesian product of keys for each combination

                          results = {}
                          for i in range(2, 4):
                          a = [
                          [
                          results.update({"_".join(y): " and ".join([k[j] for j in y])})
                          for y in product(*x)
                          ]
                          for x in combinations(t, i)
                          if dict1 in x
                          ]

                          results


                          Output:



                          {'A_B': 'a and b',
                          'A_B_F': 'a and b and f',
                          'A_B_G': 'a and b and g',
                          'A_C': 'a and c',
                          'A_C_F': 'a and c and f',
                          'A_C_G': 'a and c and g',
                          'A_D': 'a and d',
                          'A_D_F': 'a and d and f',
                          'A_D_G': 'a and d and g',
                          'A_E': 'a and e',
                          'A_E_F': 'a and e and f',
                          'A_E_G': 'a and e and g',
                          'A_F': 'a and f',
                          'A_G': 'a and g'}





                          share|improve this answer










                          New contributor




                          Lante Dellarovere is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
                          Check out our Code of Conduct.










                          Here a dirty, but working, solution that makes use of itertools



                          from itertools import product, combinations


                          # create a list and sum dict to be used later
                          t = [dict1, dict2, dict3]
                          k = {}
                          for d in t:
                          k.update(d)


                          # iterate over "i" order of combinations ("dict1_X" or "dict1_X_Y") and
                          # the cartesian product of keys for each combination

                          results = {}
                          for i in range(2, 4):
                          a = [
                          [
                          results.update({"_".join(y): " and ".join([k[j] for j in y])})
                          for y in product(*x)
                          ]
                          for x in combinations(t, i)
                          if dict1 in x
                          ]

                          results


                          Output:



                          {'A_B': 'a and b',
                          'A_B_F': 'a and b and f',
                          'A_B_G': 'a and b and g',
                          'A_C': 'a and c',
                          'A_C_F': 'a and c and f',
                          'A_C_G': 'a and c and g',
                          'A_D': 'a and d',
                          'A_D_F': 'a and d and f',
                          'A_D_G': 'a and d and g',
                          'A_E': 'a and e',
                          'A_E_F': 'a and e and f',
                          'A_E_G': 'a and e and g',
                          'A_F': 'a and f',
                          'A_G': 'a and g'}






                          share|improve this answer










                          New contributor




                          Lante Dellarovere is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
                          Check out our Code of Conduct.









                          share|improve this answer



                          share|improve this answer








                          edited yesterday





















                          New contributor




                          Lante Dellarovere is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
                          Check out our Code of Conduct.









                          answered yesterday









                          Lante DellarovereLante Dellarovere

                          1716




                          1716




                          New contributor




                          Lante Dellarovere is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
                          Check out our Code of Conduct.





                          New contributor





                          Lante Dellarovere is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
                          Check out our Code of Conduct.






                          Lante Dellarovere is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
                          Check out our Code of Conduct.






























                              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%2f55636895%2fcompute-the-product-of-3-dictionaries-and-concatenate-keys-and-values%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

                              GameSpot

                              connect to host localhost port 22: Connection refused

                              Getting a Wifi WPA2 wifi connection