docs: def list_ngram_range(token_list, *args, **kwargs):
      """Return a list of n-tuples, one for each possible sequence of n items in the token_list
  
      Arguments:
        join (bool or str): if str, then join ngrom tuples on it before returning
           True is equivalent to join=' '
           default = True
  
      >>> list_ngram_range('goodbye cruel world'.split(), 0, 2, join=False)
      [('goodbye',), ('cruel',), ('world',), ('goodbye', 'cruel'), ('cruel', 'world')]
      >>> list_ngram_range('goodbye cruel world'.split(), 2, join=False)
      [('goodbye',), ('cruel',), ('world',), ('goodbye', 'cruel'), ('cruel', 'world')]
      >>> list_ngram_range('goodbye cruel world'.split(), 0, 2, join='|')
      ['goodbye', 'cruel', 'world', 'goodbye|cruel', 'cruel|world']
      >>> list_ngram_range('goodbye cruel world'.split(), 0, 2, join=True)
      ['goodbye', 'cruel', 'world', 'goodbye cruel', 'cruel world']
      """
      m, n = (args if len(args) > 1 else ((0, args[0]) if args else (0, 1)))
      join = args[2] if len(args) > 2 else kwargs.pop('join', True)
      return list(chain(*(list_ngrams(token_list, i + 1, join=join) for i in range(0, n))))