code: def expand(template, variables):
      
      def _sub(match):
          expression = match.group(1)
          operator = ""
          if expression[0] in OPERATOR:
              operator = expression[0]
              varlist = expression[1:]
          else:
              varlist = expression
  
          safe = ""
          if operator in ["+", "#"]:
              safe = RESERVED
          varspecs = varlist.split(",")
          varnames = []
          defaults = {}
          for varspec in varspecs:
              default = None
              explode = False
              prefix = None
              if "=" in varspec:
                  varname, default = tuple(varspec.split("=", 1))
              else:
                  varname = varspec
              if varname[-1] == "*":
                  explode = True
                  varname = varname[:-1]
              elif ":" in varname:
                  try:
                      prefix = int(varname[varname.index(":")+1:])
                  except ValueError:
                      raise ValueError("non-integer prefix '{0}'".format(
                         varname[varname.index(":")+1:]))
                  varname = varname[:varname.index(":")]
              if default:
                  defaults[varname] = default
              varnames.append((varname, explode, prefix))
  
          retval = []
          joiner = operator
          start = operator
          if operator == "+":
              start = ""
              joiner = ","
          if operator == "#":
              joiner = ","
          if operator == "?":
              joiner = "&"
          if operator == "&":
              start = "&"
          if operator == "":
              joiner = ","
          for varname, explode, prefix in varnames:
              if varname in variables:
                  value = variables[varname]
                  if not value and value != "" and varname in defaults:
                      value = defaults[varname]
              elif varname in defaults:
                  value = defaults[varname]
              else:
                  continue
              expanded = TOSTRING[operator](
                varname, value, explode, prefix, operator, safe=safe)
              if expanded is not None:
                  retval.append(expanded)
          if len(retval) > 0:
              return start + joiner.join(retval)
          else:
              return ""
  
      return TEMPLATE.sub(_sub, template)
docs: Expand template as a URI Template using variables.