How to create a function (Iteration/Recursion) to run over a dictionary of tuples in Python?
Question: I have a Python dictionary of lists like this one:

    
    
    d = {'A': [(4, 4, 3), [1, 2, 3, 4, 5]],
         'B': [(2, 1, 2), [5, 4, 3, 2, 1]],
         'C': [(4, 1, 1), [2, 4, 1, 2, 4]]}
    

I need to create a formula that accesses the elements of the dictionary and,
for every value `[t, l]`:

  * Calculates the mean of `t` (let's call this `m`);
  * Takes a random sample `s`, with replacement and of length `len(t)`, from `l`;
  * Compares `m` with the mean of `s` \- `True` if `m` is greater than the mean of `s`, `False` otherwise;
  * Repeats this process 10,000 times 
  * Returns the percentage of times `m` is greater than the mean of `s`.

The output should look like:

    
    
    In [16]: test(d)   
    Out[16]: {'A': 0.5, 'B': 0.9, 'C': 0.4}
    

I think I'm not that far from an answer, this is what I have tried:

    
    
    def test(dict):
        def mean_diff(dict):
            for k, (v0, v1) in dict.iteritems():
                m = np.mean(v0) > (np.mean(npr.choice(v1, size=(1, len(v0)), replace=True)))
                return ({k: m})
        for k, (v0, v1) in dict.iteritems():
            bootstrap = np.array([means_diff(dict) for _ in range(10000)])
            rank = float(np.sum(bootstrap))/10000
            return ({k: rank})
    

However, I got:

    
    
    RuntimeError: maximum recursion depth exceeded while calling a Python object
    


Answer: I'd use a list comprehension that essentially selects a random value and
compares it to the mean. This will produce a list of True/False. If you take
the mean of that, it will be averaging a list of 1's and 0's, so it will give
you the aggregate probability.

    
    
    import numpy as np
    
    d = {'A': [(4, 4, 3), [1, 2, 3, 4, 5]],
         'B': [(2, 1, 2), [5, 4, 3, 2, 1]],
         'C': [(4, 1, 1), [2, 4, 1, 2, 4]]}
    
    def makeRanks(d):
        rankDict = {}
        for key in d:
            tup = d[key][0]
            mean = np.mean(tup)
            l = d[key][1]
            rank = np.mean([mean > np.mean(np.random.choice(l,len(tup))) for _ in range(10000)])
            rankDict[key] = rank
        return rankDict
    

Testing

    
    
    >>> makeRanks(d)
    {'C': 0.15529999999999999, 'A': 0.72130000000000005, 'B': 0.031899999999999998}
    

