def estimate_mean(sample, values, weights=None):
    """
    estimate_mean(sample, values, weights=None)

    Based on a sample, estimate and return the average value over all existing items. 

    Parameters
    ----------  
    sample:       - a sample of items (iterable)
    values:       - function: item -> value
    weights:      - function: item -> sampling_weight of this item   
    """           

    if weights==None:   # uniform sample
        weights = lambda x: 1
    
    up = down = 0.
    for v in sample:
        up += 1.*values(v)/weights(v) 
        down += 1./weights(v)
    return up/down