class_docstr: Vocabulary class that handles parsing and printing composite values such as
  compositional XPOS and universal morphological features (UFeats).
  
  Two key options are `keyed` and `sep`. `sep` specifies the separator used between
  different parts of the composite values, which is `|` for UFeats, for example.
  If `keyed` is `True`, then the incoming value is treated similarly to UFeats, where
  each part is a key/value pair separated by an equal sign (`=`). There are no inherit
  order to the keys, and we sort them alphabetically for serialization and deserialization.
  Whenever a part is absent, its internal value is a special `<EMPTY>` symbol that will
  be treated accordingly when generating the output. If `keyed` is `False`, then the parts
  are treated as positioned values, and `<EMPTY>` is used to pad parts at the end when the
  incoming value is not long enough.
code: def id2unit(self, id):
      # special case: allow single ids for vocabs with length 1
      if len(self._id2unit) == 1 and not isinstance(id, Iterable):
          id = (id,)
      items = []
      for v, k in zip(id, self._id2unit.keys()):
          if v == EMPTY_ID:
              continue
          if self.keyed:
              items.append("{}={}".format(k, self._id2unit[k][v]))
          else:
              items.append(self._id2unit[k][v])
      if self.sep is not None:
          res = self.sep.join(items)
          if res == "":
              res = "_"
          return res
      else:
          return items
  
imports: from copy import copy
  from collections import Counter, OrderedDict
  from collections.abc import Iterable
  import os
  import pickle
label_desc: Use image node_id 4 for calling the CompositeVocab obj's underlying member method code with example usage: obj.id2unit(id) and returns: res, items