def find_bands(bands, target_avg, target_range, min_shows):
    """
    Searches dictionary of bands with band name as keys and
    competition scores as values for bands that are within the
    range of the target average and have performed the minimum
    number of shows. Returns a list of bands that meet the search
    criteria.

    Parameters:
        bands: Dictionary with band name as keys and scores as values.
        target_avg: Tuple containing the average to look for and the
        amount of scores to look at.
        target_range: Range to look away from the target average.
        min_shows: Minimum number of shows to be eligible.
    Returns:
        List of bands that meet the search criteria.

    >>> DCI = {'Blue Devils': [98.2, 97.1, 99.1, 97.3, 98.2], \
        'Blue Coats': [98, 96.5, 97.2, 93, 92.1, 92, 97.4], \
        'Carolina Crown': [75.7, 82.8, 86.1, 98.2], \
        'The Cadets': [96.1, 93.4, 81, 78, 57.9, 86, 71.2, 35.5], \
        'Mandarins': [89.3, 88.1, 85.6, 83.8, 79.1, 88.4, 75.7], \
        'Little Rocks':[42], \
        'Logan Colts':[98.2, 84.4, 69.2, 42, 84]}

    >>> find_bands(DCI, (0, 10), 30, 2)
    []
    >>> find_bands(DCI, (90, 5), 5, 7)
    ['Mandarins']
    >>> find_bands(DCI, (70, 8), 10, 5)
    ['The Cadets', 'Logan Colts']
    >>> find_bands(DCI, (95, 3), 5, 4)
    ['Blue Devils', 'Blue Coats', 'The Cadets']

    # My doctests
    >>> find_bands(DCI, (42, 10), 1, 1)
    ['Little Rocks']

    >>> find_bands(DCI, (87, 10), 5, 5)
    ['Mandarins']

    >>> DCI2 = {'UCSD': [100, 99, 100, 100, 100, 100], \
        'UCLA': [50, 49, 100, 100, 100], \
        'UCD': [90, 90, 87, 45, 79]}
    >>> find_bands(DCI2, (95, 3), 5, 4)
    ['UCSD']
    >>> find_bands(DCI2, (75, 5), 10, 4)
    ['UCLA', 'UCD']
    """
    search_range = [target_avg[0] - target_range, target_avg[0] + target_range]
    lower_bound = search_range[0]
    upper_bound = search_range[1]
    noted_scores = target_avg[1]
    score_index = 1

    in_range = lambda avg: (avg >= lower_bound and avg <= upper_bound)
    score_avg = lambda scores, kept_scores: sum(scores) / len(scores) \
        if len(scores) <= kept_scores \
        else sum(scores[0:kept_scores]) / kept_scores

    return list(map(lambda name: name[0], \
            list(filter(lambda band: \
            in_range(score_avg(band[score_index], noted_scores)), \
            filter(lambda band: True if len(band[score_index]) >= min_shows \
            else False, list(bands.items()))))))