I need to generate list of all allowable test combination values of of actor, action and subject

 'actor': ['man', 'woman', 'baby'], 
 'action': ['play', 'cry'], 
 'subject': ['mathematica', 'lingvo']

I get itertools.produce and apply restriction that actor=man can't coexist with action and actor=baby can't coexist with subject

import itertools
from pprint import pprint

data = {'actor': ['man', 'woman', 'baby'], 'action': ['play', 'cry'], 'subject': ['mathematica', 'lingvo']}

def set_keys(*x):
    return tuple(zip(data.keys(), x))

def reduce(*x):
    dict_x = dict(x)
    if dict_x['actor'] == 'man':
        del dict_x['action']
    elif dict_x['actor'] == 'baby':
        del dict_x['subject']

    return tuple(dict_x.items())

def distict(*x):
    return dict(x[0])

product = itertools.product(*data.values())
product_with_keys = itertools.starmap(set_keys, product)

# pprint(list(product_with_keys))

reduced_product_with_keys = itertools.starmap(reduce, product_with_keys)
# pprint(list(reduced_product_with_keys))

grouped = itertools.groupby(reduced_product_with_keys)
# pprint(dict(grouped))

distinct = itertools.starmap(distict, grouped)

Here is a result that suits me:

[{'actor': 'man', 'subject': 'mathematica'},
{'actor': 'man', 'subject': 'lingvo'}, 
{'actor': 'man', 'subject': 'mathematica'},
{'actor': 'man', 'subject': 'lingvo'},
{'action': 'play', 'actor': 'woman', 'subject': 'mathematica'},
{'action': 'play', 'actor': 'woman', 'subject': 'lingvo'},
{'action': 'cry', 'actor': 'woman', 'subject': 'mathematica'},
{'action': 'cry', 'actor': 'woman', 'subject': 'lingvo'},
{'action': 'play', 'actor': 'baby'},
{'action': 'cry', 'actor': 'baby'}]

I am not very happy with how solved the removal of identical records

  • \$\begingroup\$ In general, I would like to create a rules which item from one list can not coexist with another item from another list \$\endgroup\$ – Александр Королёв Mar 16 '19 at 21:56
  • 5
    \$\begingroup\$ Welcome to Code Review! I'm afraid this question does not match what this site is about. Code Review is about improving existing, working code. Code Review is not the site to ask for help in fixing or changing what your code does. Once the code does what you want, we would love to help you do the same thing in a cleaner way! Please see our help center for more information. \$\endgroup\$ – Vogel612 Mar 16 '19 at 22:07
  • \$\begingroup\$ keys, values = zip(*params.items()) is needlessly computing two lists. Instead you could use keys = params.keys(); values = params.values() \$\endgroup\$ – 301_Moved_Permanently Mar 17 '19 at 16:54
  • \$\begingroup\$ I provide my solution \$\endgroup\$ – Александр Королёв Mar 18 '19 at 9:57

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Browse other questions tagged or ask your own question.