code: def split_in_blocks(sequence, hint, weight=lambda item: 1, key=nokey):
      
      if isinstance(sequence, int):
          return split_in_slices(sequence, hint)
      elif hint in (0, 1) and key is nokey:  # do not split
          return [sequence]
      elif hint in (0, 1):  # split by key
          blocks = []
          for k, group in groupby(sequence, key).items():
              blocks.append(group)
          return blocks
      items = sorted(sequence, key=lambda item: (key(item), weight(item)))
      assert hint > 0, hint
      assert len(items) > 0, len(items)
      total_weight = float(sum(weight(item) for item in items))
      return block_splitter(items, math.ceil(total_weight / hint), weight, key)
docs: Split the `sequence` in a number of WeightedSequences close to `hint`.
  
      :param sequence: a finite sequence of items
      :param hint: an integer suggesting the number of subsequences to generate
      :param weight: a function returning the weigth of a given item
      :param key: a function returning the key of a given item
  
      The WeightedSequences are of homogeneous key and they try to be
      balanced in weight. For instance
  
       >>> items = 'ABCDE'
       >>> list(split_in_blocks(items, 3))
       [<WeightedSequence ['A', 'B'], weight=2>, <WeightedSequence ['C', 'D'], weight=2>, <WeightedSequence ['E'], weight=1>]