I have a list of rectangles as tuples (x, y, w, h).  I need to find which ones intersect and if they do, average all the intersecting rectangles into a new rectangle. I also track the resultant averaged rectangle weight (the number of intersecting rectangles) as an addition member in the new tuple. (x, y, w, h, weight)The final return is resultant list of averaged sorted by weight.I am looking for feedback on how to improve performance and make it even more pythonic.  Or, as I have discovered many times in python, there may a completely different and better way to approach the problem (such as with NumPy).I pass a list of rect tuples to ordered_average_intersecting_rects:import numpy as npdef rects_intersect(r1, r2):    hoverlaps = (r1[0] <= r2[0] + r2[2]) and (r1[0] + r1[2] >= r2[0])    voverlaps = (r1[1] <= r2[1] + r2[3]) and (r1[1] + r1[3] >= r2[1])    return hoverlaps and voverlapsdef average_rects(rects):    x = np.average([coord[0] for coord in rects])    y = np.average([coord[1] for coord in rects])    w = np.average([coord[2] for coord in rects])    h = np.average([coord[3] for coord in rects])    return x, y, w, h, len(rects)def ordered_average_intersecting_rects(rects):    intersecting_rect_clusters = []    while rects:  # modified from `while len(rect) > 0:` (janos feedback)        r1 = rects[0]        rect_cluster = [r1]        for r2 in rects[1:]:            if rects_intersect(r1, r2):                rect_cluster.append(r2)                rects.remove(r2)        rects.remove(r1)        intersecting_rect_clusters.append(rect_cluster)    averaged_rects = [average_rects(cluster) for cluster in intersecting_rect_clusters]    averaged_rects.sort(key=lambda w: w[4], reverse=True)    return averaged_rectsHere is my unit test to help understand how the code is being used:def test_ordered_average_intersecting_rects(self):    # Arrange    rects = [(150, 55, 40, 20, 0),             (160, 40, 20, 20, 0),             (100, 120, 20, 20, 0),             (45, 10, 15, 30, 0),             (50, 25, 25, 20, 0),             (35, 35, 20, 30, 0)]    # Act    with test_helpers.Timer('average_intersecting_rects') as t:        result = ordered_average_intersecting_rects(rects)    # Assert    assert len(result) == 3    cluster1 = result[0]    assert cluster1[4] == 3    assert int(cluster1[0]) == 43    assert int(cluster1[1]) == 23    assert int(cluster1[2]) == 20    assert int(cluster1[3]) == 26    cluster2 = result[1]    assert cluster2[4] == 2    assert cluster2[0] == 155    assert cluster2[1] == 47.5    assert cluster2[2] == 30    assert cluster2[3] == 20    cluster3 = result[2]    assert cluster3[4] == 1    assert cluster3[0] == 100    assert cluster3[1] == 120    assert cluster3[2] == 20    assert cluster3[3] == 20
Averaging a list of intersecting rectangles
python;performance;numpy