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
Using et al. for a last / senior author rather than for a first author
Why was the term "discrete" used in discrete logarithm?
What are 'alternative tunings' of a guitar and why would you use them? Doesn't it make it more difficult to play?
Is it true to say that an hosting provider's DNS server is what links the entire hosting environment to ICANN?
How can I fade player when goes inside or outside of the area?
How can players work together to take actions that are otherwise impossible?
What do you call a plan that's an alternative plan in case your initial plan fails?
If Jon Snow became King of the Seven Kingdoms what would his regnal number be?
Did Xerox really develop the first LAN?
How to find all the available tools in macOS terminal?
Should gear shift center itself while in neutral?
Why does Python start at index -1 when indexing a list from the end?
Does surprise arrest existing movement?
Stars Make Stars
Do I really need recursive chmod to restrict access to a folder?
Is it true that "carbohydrates are of no use for the basal metabolic need"?
What is the longest distance a 13th-level monk can jump while attacking on the same turn?
Models of set theory where not every set can be linearly ordered
I am not a queen, who am I?
Why don't the Weasley twins use magic outside of school if the Trace can only find the location of spells cast?
Sorting numerically
How to recreate this effect in Photoshop?
Does accepting a pardon have any bearing on trying that person for the same crime in a sovereign jurisdiction?
Java 8 stream max() function argument type Comparator vs Comparable
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
2056
2056
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