I want to calculate the Cartesian product of n copies of a small list, marker=[0,1,2]. I want to use these Cartesian product tuples as keys in a dictionary. The value per each key is to be a numpy array with n random floats between 0 and 1.The only twist is that for each key:value pair in the dictionary, if the key has a non-zero number in its index a, I want the corresponding value np.array to have np.nan for the same index.Below is the function I wrote for that. My question is whether there is a quicker / more efficient way to get the same result.import itertoolsimport numpy as npdef create_constrained_dict(n, markers):    '''    Create cartesian product of a the same list repeated n times    It returns a dictionary whose keys are the cartesian products of the    input lists. The values of the dictionary are numpy arrays of length 'n'.    If the corresponding dictionary key element for a value is not zero, we replace the value    with np.nan.    Belwo is an example:    So for some key-value pair, NaN's would be lcoated as follows:          d={(0,0,1): np.array([0.1234, 0.7543, np.nan]),            (1,2,1): np.array([np.nan, np.nan, np.nan]),            (1,0,1): np.array([np.nan, 0.2634, np.nan]),    }     '''    d = dict()    for element in itertools.product(*[markers  for i in xrange(n)]):        d[element] = np.random.uniform(0, 1,n)        for i in xrange(n):            if element[i] !=0:                d[element][i]= np.nan    return drep_num = 3marker = [0,1,2]d = create_constrained_dict(rep_num, marker)The output looks like this:print d{  (0, 1, 1): array([ 0.84049621,         nan,         nan]),  (0, 1, 2): array([ 0.17520962,         nan,         nan]),  (1, 0, 1): array([        nan,  0.96110224,         nan]),  (0, 2, 1): array([ 0.10395044,         nan,         nan]),  (2, 2, 0): array([        nan,         nan,  0.60131589]),  (0, 2, 0): array([ 0.64515576,         nan,  0.05946614]),  (0, 2, 2): array([ 0.02054272,         nan,         nan]),  (1, 0, 0): array([        nan,  0.98472074,  0.93688277]),  (2, 0, 1): array([        nan,  0.64348266,         nan]),  (1, 2, 0): array([        nan,         nan,  0.71462777]),  (2, 0, 0): array([        nan,  0.98370414,  0.3517195 ]),  (1, 2, 1): array([ nan,  nan,  nan]),  (0, 0, 2): array([ 0.29771489,  0.83521032,         nan]),  (2, 2, 2): array([ nan,  nan,  nan]),  (1, 2, 2): array([ nan,  nan,  nan]),  (2, 0, 2): array([        nan,  0.95682699,         nan]),  (0, 0, 1): array([ 0.26649784,  0.38120757,         nan]),  (0, 0, 0): array([ 0.98960411,  0.70080955,  0.25540202]),  (2, 1, 2): array([ nan,  nan,  nan]),  (1, 1, 1): array([ nan,  nan,  nan]),  (0, 1, 0): array([ 0.94015447,         nan,  0.56849242]),  (1, 1, 0): array([        nan,         nan,  0.30593067]),  (2, 1, 0): array([        nan,         nan,  0.74205853]),  (2, 2, 1): array([ nan,  nan,  nan]),  (2, 1, 1): array([ nan,  nan,  nan]),  (1, 1, 2): array([ nan,  nan,  nan]),  (1, 0, 2): array([        nan,  0.27788722,         nan])}
Python Cartesian Product in a constrained dictonary
python;python 2.7;numpy;dictionary
Instead of itertools.product(*[markers  for i in xrange(n)]) use itertools.product(markers, repeat=n)Instead of creating three random values and replace it with nan use List Comprehensions.dict([(key, value) for key, value in ...]) creates dict object.[bool and [a] or [b]][0] - safer version of bool and a or b - one-linear version of:if bool:    aelse:    bAnd final version:import itertoolsimport numpy as npdef create_constrained_dict(n, markers):    d = dict([(element, np.array([(i == 0 and [np.random.uniform(0, 1)] or [np.nan])[0]                                  for i in element]))              for element in itertools.product(markers, repeat=n)])    return dEDITVersion without np.array - 2 times faster (thanks @JoeWallis):import itertoolsimport numpy as npdef create_constrained_dict(n, markers):    d = dict([(element, [(i == 0 and [np.random.uniform(0, 1)] or [np.nan])[0]                         for i in element]))              for element in itertools.product(markers, repeat=n)])    return d