docs: def _weighted_selection(l, n):
      """
          Selects  n random elements from a list of (weight, item) tuples.
          Based on code snippet by Nick Johnson
      """
      cuml = []
      items = []
      total_weight = 0.0
      for weight, item in l:
          total_weight += weight
          cuml.append(total_weight)
          items.append(item)
  
      return [items[bisect.bisect(cuml, random.random()*total_weight)] for _ in range(n)]