首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >使用IDs数组将重复字典项转换为唯一项

使用IDs数组将重复字典项转换为唯一项
EN

Stack Overflow用户
提问于 2017-07-17 19:31:41
回答 4查看 129关注 0票数 1

我有一个字典列表,其中一个字典值name包含要规范化的重复数据。清单如下:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
[
    {'name': 'Craig McKray', 'document_id': 50, 'annotation_id': 8}, 
    {'name': 'None on file', 'document_id': 40, 'annotation_id': 5},
    {'name': 'Craig McKray', 'document_id': 50, 'annotation_id': 9},
    {'name': 'Western Union', 'document_id': 61, 'annotation_id': 11}
]

我想要做的是创建一个只包含唯一名称的新字典。但我需要追踪document_ids和annotation_ids。有时document_ids是相同的,但我只需要跟踪它们与名称的关联。因此,上述清单将变成:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
[
     {'name': 'Craig McKray', 'document_ids': [50], 'annotation_ids': [8, 9]},
     {'name': 'None on file', 'document_ids': [40], 'annotation_id': [5]},
     {'name': 'Western Union', 'document_ids': [61], 'annotation_ids': [11]}
]

下面是我到目前为止尝试过的代码:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
result = []
# resolve duplicate names
result_row = defaultdict(list)
for item in data:
    for double in data:
        if item['name'] == double['name']:
            result_row['name'] = item['name']
            result_row['record_ids'].append(item['document_id'])
            result_row['annotation_ids'].append(item['annotation_id'])
            result.append(result_row)

代码的主要问题是比较和查找重复项,但是当我迭代到下一项时,它再次发现重复创建了无限循环。我怎样才能编辑代码,这样它就不会一遍又一遍地比较重复的代码?

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2017-07-17 19:37:39

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
new = dict()
for x in people:
    if x['name'] in new:
        new[x['name']].append({'document_id': x['document_id'], 'annotation_id': x['annotation_id']})
    else:
        new[x['name']] = [{'document_id': x['document_id'], 'annotation_id': x['annotation_id']}]

这并不是你想要的,但是格式应该做你想要做的事情。

这是输出:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
{'Craig McKray': [{'annotation_id': 8, 'document_id': 50}, {'annotation_id': 9, 'document_id': 50}], 'Western Union': [{'annotation_id': 11, 'document_id': 61}], 'None on file': [{'annotation_id': 5, 'document_id': 40}]}

在这里,我认为这可能对你更好:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
from collections import defaultdict
new = defaultdict(dict)

for x in people:
    if x['name'] in new:
        new[x['name']]['document_ids'].append(x['document_id'])
        new[x['name']]['annotation_ids'].append(x['annotation_id'])
    else:
        new[x['name']]['document_ids'] = [x['document_id']]
        new[x['name']]['annotation_ids'] = [x['annotation_id']]
票数 1
EN

Stack Overflow用户

发布于 2017-07-17 20:08:54

一种更实用的itertools.groupby方法可能是这样的。有点神秘,所以我会解释的。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
from itertools import groupby
from operator import itemgetter

inp = [
    {'name': 'Craig McKray', 'document_id': 50, 'annotation_id': 8}, 
    {'name': 'None on file', 'document_id': 40, 'annotation_id': 5},
    {'name': 'Craig McKray', 'document_id': 50, 'annotation_id': 9},
    {'name': 'Western Union', 'document_id': 61, 'annotation_id': 11}
]

def groupvals(vals):

    namegetter = itemgetter('name')
    doccanngetter = itemgetter('document_id', 'annotation_id')

    for grouper, grps in groupby(sorted(vals, key=namegetter), key=namegetter):

        docanns = [set(param) for param in zip(*(doccanngetter(g) for g in grps))]
        yield {'name': grouper, 'document_id': list(docanns[0]), 'annotation_id': list(docanns[1])}


for result in groupvals(inp):
    print(result)

要使用groupby,您需要一个排序列表。所以先按名字分类。那么groupby的名字。接下来,您可以提取document_idannotation_id参数并压缩它们。这样做的效果是将所有的document_ids放到一个列表中,将所有的annotation_id放到另一个列表中。然后,您可以调用set来删除重复项,并使用生成器作为dict生成每个元素。

我使用了生成器,因为它避免了建立结果列表的需要。但如果你愿意的话你可以这么做。

票数 0
EN

Stack Overflow用户

发布于 2017-07-17 20:36:46

我对这个问题的看法是:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
result = []
# resolve duplicate names
all_names = []
for i, item in enumerate(data):
    if item['name'] in all_names:
        continue
    result_row = {'name': item['name'], 'record_ids': [item['document_id']],
                  'annotation_ids':[item['annotation_id']]}
    all_names.append(item['name'])
    for j, double in enumerate(data):
        if item['name'] == double['name'] and i != j:
            result_row['record_ids'].append(double['document_id'])
            result_row['annotation_ids'].append(double['annotation_id'])
        result.append(result_row)
票数 0
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/45157013

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文