Compute the product of 3 dictionaries and concatenate keys and values Announcing the arrival of Valued Associate #679: Cesar Manara Planned maintenance scheduled April 17/18, 2019 at 00:00UTC (8:00pm US/Eastern) The Ask Question Wizard is Live! Data science time! April 2019 and salary with experience Should we burninate the [wrap] tag?“Least Astonishment” and the Mutable Default ArgumentHow to merge two dictionaries in a single expression?How do I sort a list of dictionaries by a value of the dictionary?How do I sort a dictionary by value?Add new keys to a dictionary?Check if a given key already exists in a dictionaryHow do I concatenate two lists in Python?Iterating over dictionaries using 'for' loopsHow to remove a key from a Python dictionary?check two dictionaries that have similar keys but different valueshow to compare two dictionaries to check if a key is present in both of them
Bonus calculation: Am I making a mountain out of a molehill?
What are the pros and cons of Aerospike nosecones?
Is there a documented rationale why the House Ways and Means chairman can demand tax info?
What LEGO pieces have "real-world" functionality?
When is phishing education going too far?
How to recreate this effect in Photoshop?
Should I call the interviewer directly, if HR aren't responding?
ListPlot join points by nearest neighbor rather than order
Can Pao de Queijo, and similar foods, be kosher for Passover?
Why does Python start at index 1 when iterating an array backwards?
When to stop saving and start investing?
Is it true that "carbohydrates are of no use for the basal metabolic need"?
If a contract sometimes uses the wrong name, is it still valid?
What are 'alternative tunings' of a guitar and why would you use them? Doesn't it make it more difficult to play?
How do I keep my slimes from escaping their pens?
Is there a concise way to say "all of the X, one of each"?
Is the Standard Deduction better than Itemized when both are the same amount?
WAN encapsulation
Why is "Captain Marvel" translated as male in Portugal?
How to bypass password on Windows XP account?
Does accepting a pardon have any bearing on trying that person for the same crime in a sovereign jurisdiction?
Why is "Consequences inflicted." not a sentence?
How to find all the available tools in macOS terminal?
Does polymorph use a PC’s CR or its level?
Compute the product of 3 dictionaries and concatenate keys and values
Announcing the arrival of Valued Associate #679: Cesar Manara
Planned maintenance scheduled April 17/18, 2019 at 00:00UTC (8:00pm US/Eastern)
The Ask Question Wizard is Live!
Data science time! April 2019 and salary with experience
Should we burninate the [wrap] tag?“Least Astonishment” and the Mutable Default ArgumentHow to merge two dictionaries in a single expression?How do I sort a list of dictionaries by a value of the dictionary?How do I sort a dictionary by value?Add new keys to a dictionary?Check if a given key already exists in a dictionaryHow do I concatenate two lists in Python?Iterating over dictionaries using 'for' loopsHow to remove a key from a Python dictionary?check two dictionaries that have similar keys but different valueshow to compare two dictionaries to check if a key is present in both of them
.everyoneloves__top-leaderboard:empty,.everyoneloves__mid-leaderboard:empty,.everyoneloves__bot-mid-leaderboard:empty height:90px;width:728px;box-sizing:border-box;
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
add a comment |
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
add a comment |
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
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
python
asked Apr 11 at 16:08
Old-SchoolOld-School
726
726
add a comment |
add a comment |
4 Answers
4
active
oldest
votes
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'
1
isfunctools
supposed to beitertools
?
– Ben Jones
Apr 11 at 16:23
1
@BenJones Yeah sure my bad, I always mix them up...
– Right leg
Apr 11 at 16:24
No worries. Now I know aboutfunctools
!
– Ben Jones
Apr 11 at 16:25
1
@BenJones Wanna learn about some more magic? Check outmore_itertools
:)
– Right leg
Apr 11 at 16:27
Adding an outer loop offor dicts in ((dict1, dict2), (dict1, dict3), (dict1, dict2, dict3)):
and making the inner loopfor t in product(*[d.items() for d in dicts]):
would let you produce the result with minimal code repetition.
– ShadowRanger
Apr 11 at 16:27
|
show 3 more comments
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'
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 fordef combos(d, c=None): if c is None: c = []
. See stackoverflow.com/questions/1132941/…
– Right leg
Apr 11 at 16:59
add a comment |
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.
New contributor
add a comment |
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'
New contributor
add a comment |
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
);
);
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
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'
1
isfunctools
supposed to beitertools
?
– Ben Jones
Apr 11 at 16:23
1
@BenJones Yeah sure my bad, I always mix them up...
– Right leg
Apr 11 at 16:24
No worries. Now I know aboutfunctools
!
– Ben Jones
Apr 11 at 16:25
1
@BenJones Wanna learn about some more magic? Check outmore_itertools
:)
– Right leg
Apr 11 at 16:27
Adding an outer loop offor dicts in ((dict1, dict2), (dict1, dict3), (dict1, dict2, dict3)):
and making the inner loopfor t in product(*[d.items() for d in dicts]):
would let you produce the result with minimal code repetition.
– ShadowRanger
Apr 11 at 16:27
|
show 3 more comments
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'
1
isfunctools
supposed to beitertools
?
– Ben Jones
Apr 11 at 16:23
1
@BenJones Yeah sure my bad, I always mix them up...
– Right leg
Apr 11 at 16:24
No worries. Now I know aboutfunctools
!
– Ben Jones
Apr 11 at 16:25
1
@BenJones Wanna learn about some more magic? Check outmore_itertools
:)
– Right leg
Apr 11 at 16:27
Adding an outer loop offor dicts in ((dict1, dict2), (dict1, dict3), (dict1, dict2, dict3)):
and making the inner loopfor t in product(*[d.items() for d in dicts]):
would let you produce the result with minimal code repetition.
– ShadowRanger
Apr 11 at 16:27
|
show 3 more comments
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'
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'
edited Apr 11 at 16:39
answered Apr 11 at 16:19
Right legRight leg
8,56242450
8,56242450
1
isfunctools
supposed to beitertools
?
– Ben Jones
Apr 11 at 16:23
1
@BenJones Yeah sure my bad, I always mix them up...
– Right leg
Apr 11 at 16:24
No worries. Now I know aboutfunctools
!
– Ben Jones
Apr 11 at 16:25
1
@BenJones Wanna learn about some more magic? Check outmore_itertools
:)
– Right leg
Apr 11 at 16:27
Adding an outer loop offor dicts in ((dict1, dict2), (dict1, dict3), (dict1, dict2, dict3)):
and making the inner loopfor t in product(*[d.items() for d in dicts]):
would let you produce the result with minimal code repetition.
– ShadowRanger
Apr 11 at 16:27
|
show 3 more comments
1
isfunctools
supposed to beitertools
?
– Ben Jones
Apr 11 at 16:23
1
@BenJones Yeah sure my bad, I always mix them up...
– Right leg
Apr 11 at 16:24
No worries. Now I know aboutfunctools
!
– Ben Jones
Apr 11 at 16:25
1
@BenJones Wanna learn about some more magic? Check outmore_itertools
:)
– Right leg
Apr 11 at 16:27
Adding an outer loop offor dicts in ((dict1, dict2), (dict1, dict3), (dict1, dict2, dict3)):
and making the inner loopfor t in product(*[d.items() for d in dicts]):
would let you produce the result with minimal code repetition.
– ShadowRanger
Apr 11 at 16:27
1
1
is
functools
supposed to be itertools
?– Ben Jones
Apr 11 at 16:23
is
functools
supposed to be itertools
?– Ben Jones
Apr 11 at 16:23
1
1
@BenJones Yeah sure my bad, I always mix them up...
– Right leg
Apr 11 at 16:24
@BenJones Yeah sure my bad, I always mix them up...
– Right leg
Apr 11 at 16:24
No worries. Now I know about
functools
!– Ben Jones
Apr 11 at 16:25
No worries. Now I know about
functools
!– Ben Jones
Apr 11 at 16:25
1
1
@BenJones Wanna learn about some more magic? Check out
more_itertools
:)– Right leg
Apr 11 at 16:27
@BenJones Wanna learn about some more magic? Check out
more_itertools
:)– Right leg
Apr 11 at 16:27
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
Apr 11 at 16:27
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
Apr 11 at 16:27
|
show 3 more comments
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'
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 fordef combos(d, c=None): if c is None: c = []
. See stackoverflow.com/questions/1132941/…
– Right leg
Apr 11 at 16:59
add a comment |
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'
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 fordef combos(d, c=None): if c is None: c = []
. See stackoverflow.com/questions/1132941/…
– Right leg
Apr 11 at 16:59
add a comment |
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'
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'
answered Apr 11 at 16:35
Ajax1234Ajax1234
43.2k42954
43.2k42954
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 fordef combos(d, c=None): if c is None: c = []
. See stackoverflow.com/questions/1132941/…
– Right leg
Apr 11 at 16:59
add a comment |
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 fordef combos(d, c=None): if c is None: c = []
. See stackoverflow.com/questions/1132941/…
– Right leg
Apr 11 at 16:59
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
Apr 11 at 16:59
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
Apr 11 at 16:59
add a comment |
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.
New contributor
add a comment |
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.
New contributor
add a comment |
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.
New contributor
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.
New contributor
edited Apr 11 at 16:45
New contributor
answered Apr 11 at 16:38
Sparky05Sparky05
1956
1956
New contributor
New contributor
add a comment |
add a comment |
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'
New contributor
add a comment |
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'
New contributor
add a comment |
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'
New contributor
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'
New contributor
edited Apr 11 at 18:21
New contributor
answered Apr 11 at 17:41
Lante DellarovereLante Dellarovere
26816
26816
New contributor
New contributor
add a comment |
add a comment |
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.
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function ()
StackExchange.helpers.onClickDraftSave('#login-link');
);
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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