def clean(self, ns_dict):
        for ns, values in six.iteritems(ns_dict):
            for k, v, opts in values:
                current = self
                bits = k.split('/')
                for bit in bits[:-1]:
                    bit = bit.rpartition(':')[-1]
                    m = re.search(r'^(.*)\[(\d+)\](?=\/|\Z)', bit)
                    if not m:
                        current = current.setdefault(bit, {})
                    else:
                        bit = m.group(1)
                        index = int(m.group(2)) - 1
                        if isinstance(current.get(bit), list):
                            if len(current[bit]) < (index + 1):
                                current[bit] += [{}] * (1 + index - len(current[bit]))
                            current = current[bit][index]
                        else:
                            current[bit] = [{}] * (index + 1)
                            current = current[bit][index]

                if opts.get('VALUE_IS_ARRAY') and not v:
                    v = []
                elif opts.get('VALUE_IS_STRUCT') and not v:
                    v = {}

                ns_prefix, sep, k = bits[-1].rpartition(':')

                if ns_prefix == 'stDim' and k in ('w, h'):
                    try:
                        v = int(v)
                    except (TypeError, ValueError):
                        v = None
                elif ns_prefix == 'stArea' and k in ('w', 'h', 'x', 'y'):
                    try:
                        v = float(v)
                    except (TypeError, ValueError):
                        v = None
                elif k == 'DerivedFrom' and isinstance(v, six.string_types):
                    v = re.sub(r'^xmp\.did:', '', v).lower()
                elif ns_prefix == 'crop' and k == 'json':
                    v = json.loads(v)
                elif ns_prefix == 'crop' and k == 'md5':
                    v = v.lower()

                m = re.search(r'^(.*)\[(\d+)\](?=\/|\Z)', k)
                if m:
                    current = current.setdefault(m.group(1), [{}])
                    k = int(m.group(2)) - 1

                if isinstance(current, list) or isinstance(k, six.integer_types):
                    if len(current) <= k:
                        current.append(*([{}] * (1 + k - len(current))))

                # Now assign value to current position
                try:
                    current[k] = v
                except TypeError: # Special-case if current isn't a dict.
                    current = {k: v}
                except IndexError:
                    if k != 0 or not isinstance(current, list):
                        raise
                    current = [v]
dataset/ETHPy150Open theatlantic/django-cropduster/cropduster/standalone/metadata.py/MetadataDict.clean/operator `and` -> `or`