def _trivial(L): # L is empty or has only one (mapping, weight) pair. If there is a # pair, we may still need to multiply the mapping by its weight. assert len(L) <= 1 if len(L) == 0: return IFBucket() [(result, weight)] = L if weight != 1: dummy, result = weightedUnion(IFBucket(), result, 0, weight) return result
def mass_weightedUnion(L): "A list of (mapping, weight) pairs -> their weightedUnion IFBucket." if len(L) < 2: return _trivial(L) # Balance unions as closely as possible, smallest to largest. merge = NBest(len(L)) for x, weight in L: merge.add((x, weight), len(x)) while len(merge) > 1: # Merge the two smallest so far, and add back to the queue. (x, wx), dummy = merge.pop_smallest() (y, wy), dummy = merge.pop_smallest() dummy, z = weightedUnion(x, y, wx, wy) merge.add((z, 1), len(z)) (result, weight), dummy = merge.pop_smallest() return result