通过来自另一个字典的嵌套 id 过滤字典列表

时间:2021-01-31 21:29:01

标签: python dictionary

我需要从另一个字典 (includes) 中嵌套 id 来过滤字典列表 (relationships)。这是我的实现:

def filter_includes(relationships, includes):
    def normalize(data):
        if data is None:
            return []
        return data if isinstance(data, list) else [data]

    def simplify(r):
        return ((d['type'], d['id']) for i in r for d in normalize(r[i]['data']))

    r_set = set(simplify(relationships))

    return [e for e in includes if (e['type'], e['id']) in r_set]

以下是通过的测试:

relationships = {
    'author': {
        'data': {
            'type': 'users',
            'id': '22DB1A00-0000-0000-00009BC6',
        }
    },
    'parent': {
        'data': {
            'type': 'documents',
            'id': 'BE7F4800-0000-0000-000021F6',
        }
    },
    'pages_file': {
        'data': None
    },
    'fields': {
        'data': [
            {
                'type': 'dictionary',
                'id': 'B15E5D00-0000-0000-000021F6-0001',
            },
            {
                'type': 'dictionary',
                'id': 'B15E5D00-0000-0000-000021F6-0002',
            },
        ]
    },
}

includes = [
    {'type': 'users', 'id': '22DB1A00-0000-0000-00009BC6'},
    {'type': 'dictionary', 'id': 'B15E5D00-0000-0000-000021F6-0002'},
    {'type': 'dictionary', 'id': 'B15E5D00-0000-0000-000021F6-0003'},
]


def test_filter_includes():
    result = filter_includes(relationships, includes)
    assert len(result) == 2
    assert result[0]['id'] == '22DB1A00-0000-0000-00009BC6'
    assert result[1]['id'] == 'B15E5D00-0000-0000-000021F6-0002'

    result = filter_includes({}, includes)
    assert len(result) == 0

    includes[0]['type'] = 'content_file'
    includes[1]['type'] = 'content_file'
    includes[2]['type'] = 'content_file'

    result = filter_includes(relationships, includes)
    assert len(result) == 0

    includes[0]['type'] = 'documents'
    includes[0]['id'] = 'BE7F4800-0000-0000-000021F6'

    result = filter_includes(relationships, includes)
    assert len(result) == 1
    assert result[0]['type'] == 'documents'
    assert result[0]['id'] == 'BE7F4800-0000-0000-000021F6'

澄清:过滤后我想得到的新字典应该与 id 中的嵌套字典具有相同的 typerelationships

总的来说,一切都足够好,filter_includes 函数按预期工作,但是我对更简洁的方法感兴趣。是否有更优雅\简洁的方法?

0 个答案:

没有答案