<SYSTEM_TASK:>
Solve the following problem using Python, implementing the functions described below, one line at a time
<END_TASK>
<USER_TASK:>
Description:
 def apply_unitschema(data, uschema, as_quantity=True, raise_outerr=False, convert_base=False, use_wildcards=False, list_of_dicts=False):
 """ apply the unit schema to the data Parameters data : dict uschema : dict units schema to apply as_quantity : bool if true, return values as pint.Quantity objects raise_outerr : bool raise error if a unit cannot be found in the outschema convert_to_base : bool rescale units to base units use_wildcards : bool if true, can use * (matches everything) and ? (matches any single character) list_of_dicts: bool treat list of dicts as additional branches Examples -------- {'energy': <Quantity(1, 'electron_volt')>, 'meta': None, 'other': {'y': <Quantity([4 5], 'meter')>}, 'x': <Quantity([1 2], 'nanometer')>, 'y': <Quantity([4 5], 'centimeter')>} '1.60217653e-22 kilojoule' ([4000000000.0, 5000000000.0], 'nanometer') 1.0 [4.0, 5.0] """
  # noqa: E501
    try:
        from pint import UnitRegistry
        ureg = UnitRegistry()
        from pint.quantity import _Quantity
    except ImportError:
        raise ImportError('please install pint to use this module')
    list_of_dicts = '__list__' if list_of_dicts else None

    # flatten edict
    uschema_flat = flatten(uschema, key_as_tuple=True)
    # sorted by longest key size, to get best match first
    uschema_keys = sorted(uschema_flat, key=len, reverse=True)
    data_flat = flatten(data, key_as_tuple=True, list_of_dicts=list_of_dicts)

    for dkey, dvalue in data_flat.items():
        converted = False
        for ukey in uschema_keys:

            if not len(ukey) == len(dkey[-len(ukey):]):
                continue

            if use_wildcards:
                match = all(
                    [fnmatch(d, u) for u, d in zip(ukey, dkey[-len(ukey):])])
            else:
                match = ukey == dkey[-len(ukey):]

            if match:
                # handle that it return an numpy object type if list of floats
                if isinstance(dvalue, (list, tuple)):
                    dvalue = np.array(dvalue)
                    if dvalue.dtype == np.object:
                        dvalue = dvalue.astype(float)

                if isinstance(dvalue, _Quantity):
                    quantity = dvalue.to(uschema_flat[ukey])
                else:
                    quantity = ureg.Quantity(dvalue, uschema_flat[ukey])

                if convert_base:
                    quantity = quantity.to_base_units()

                if as_quantity:
                    data_flat[dkey] = quantity
                else:
                    data_flat[dkey] = quantity.magnitude
                break

        if not converted and raise_outerr:
            raise KeyError('could not find units for {}'.format(dkey))

    return unflatten(data_flat, list_of_dicts=list_of_dicts)