def _recursive_custom_from_dfp(data):
    children = data.get('children', [])
    if children:
        operator = data['logicalOperator']
        target_list = [_recursive_custom_from_dfp(c) for c in children]
        return TargetingCriterion(target_list, operator)
    else:
        # Base case
        values = []

        if data.get('audienceSegmentIds'):
            node_key = 'AudienceSegmentCriteria'
            _id_key = 'audienceSegmentIds'
            value_ids = data[_id_key]
            for vid in value_ids:
                values.append(
                    Custom(
                        id=vid,
                        id_key=_id_key,
                        node_key=node_key,
                    )
                )
        else:
            node_key = 'CustomCriteria'
            _id_key = 'valueIds'
            value_ids = data[_id_key]
            key_id = data['keyId']
            for vid in value_ids:
                values.append(Custom(
                    id=vid,
                    id_key=_id_key,
                    parent_id=key_id,
                    node_key=node_key,
                ))

        targeting = TargetingCriterion(values, TargetingCriterion.OPERATOR.OR)
        if data['operator'] == 'IS':
            return targeting
        else:
            return ~targeting
>>> d = OrderedDict(((1, 3), (3, 2), (2, 1)))
dataset/ETHPy150Open chartbeat-labs/parselmouth/parselmouth/adapters/dfp/targeting_utils.py/_recursive_custom_from_dfp--crossover with--dataset/ETHPy150Open editorconfig/editorconfig-vim/plugin/editorconfig-core-py/editorconfig/odict.py/OrderedDict.__lt__