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'}