def _merge_ranges(ranges):
    """
	From a list of ranges (i.e.: list of tuples (start_idx, end_idx)
	Produce a list of non-overlapping ranges, merging those which overlap.
	:param ranges: list of tuples (start_idx, end_idx)
	:return: list of tuples (start_idx, end_idx)
	"""
    if ranges == []:
        return []
    ranges = sorted(ranges)
    merged_ranges = []

    cur_range = ranges[0]
    for r in ranges[1:]:
        if r[0] >= cur_range[0] and r[0] < cur_range[1]:
            cur_range = (cur_range[0], max(r[1], cur_range[1]))
        else:
            merged_ranges.append(cur_range)
            cur_range = r

    merged_ranges.append(cur_range)
    return merged_ranges