根据字典中的键和值删除重复的字典

时间:2020-06-30 04:54:01

标签: python python-3.x list dictionary duplicates

我有一个结构数据:

matches = [
                {
                    "15477084": [1]
                },
                {
                    "360418": [2]
                },
                {
                    "15477084": [1]
                },
                {
                    "15477084": [3,4]
                }
            ]

我要检查键和键中的值是否重复,我将其删除。如果键和值有许多不同的值,我将其组合。

我希望我的结果像

matches = [
                {
                    "15477084": [1,3,4]
                },
                {
                    "360418": [2]
                }
            ]

这是我的代码:

new_matches = []

for j in matches:
    newdict = dict()
    for key,value in j.items():
        if key in newdict.keys():
            if value not in newdict[key]:
                newdict[key].append(value)
                new_matches.append(newdict)
        else:
            newdict[key] = value
            new_matches.append(newdict)

但是我的结果是错误的(与数据匹配相同的结果开始了)。我不为什么我的结果是错误的。

6 个答案:

答案 0 :(得分:1)

from collections import defaultdict

result = defaultdict(list)
for item in matches:
    for k, v in item.items():
        result[k] += v

print([{k: v} for k, v in result.items()])

输出:

[{'15477084': [1, 1, 3, 4]}, {'360418': [2]}]

编辑:使最终输出唯一:

print([{k: list(set(v))} for k, v in result.items()])

答案 1 :(得分:1)

尝试一下:

from collections import defaultdict
from itertools import chain

res = defaultdict(list)

for x in matches:
    (k,) = x
    if x[k] not in res[k]:
        res[k].append(x[k])

res = {k: list(chain(*v)) for k, v in res.items()}
print(res)

输出:

{'15477084': [1, 3, 4], '360418': [2]}

答案 2 :(得分:1)

因为我喜欢大熊猫,所以我提供了一种特殊的方法来解决您的问题。也许您会喜欢。

import json
import pandas as pd


if __name__ == "__main__":
    matches = [
        {"15477084": [1]},
        {"360418": [2]},
        {"15477084": [1]},
        {"15477084": [3, 4]},
    ]
    matches_df = pd.DataFrame(matches)
    matches_df = matches_df.fillna("[]").transpose().astype(str).apply(
        lambda x: list(
            set([record for sub in x.tolist() for record in json.loads(sub)])
        ),
        axis=1,
    )
    result = matches_df.to_dict()
    print(result)

这是结果

{'15477084': [1, 3, 4], '360418': [2]}

答案 3 :(得分:0)

您可以尝试以下方法:

from collections import defaultdict

v = defaultdict(set)

for dict_values in matches:
    for key, value in sorted(dict_values.items()):
        print(key)
        for i in value:
            v[key].add(i)

输出:

defaultdict(set, {'15477084': {1, 3, 4}, '360418': {2}})

答案 4 :(得分:0)

defaultdict可以在这里提供帮助

from collections import defaultdict

res_matches = defaultdict(list)
for i in matches:
    key, value = list(i.keys())[0], list(i.values())[0]
    to_add = set(value).difference(set(res_matches[key]))
    if to_add:
        res_matches[key].extend(to_add)
print(dict(res_matches))

输出

{'15477084': [1, 3, 4], '360418': [2]}

答案 5 :(得分:0)

您的程序的问题在于,将为每次迭代创建newdict,并且它将没有任何键值对,因此该语句(如果newdict.keys()中的key)始终为false,因此else语句将被执行,它将把匹配列表中的字典追加到new_matches中。

还有语句(如果值不在newdict [key]中),这里value是一个列表,newdict [key]也将是一个列表(如果您解决了上述问题),因此要比较两个列表。即[1] == [3,4],这不是正确的。相反,您应该迭代列表中任何一个的每个值,并将其与另一个列表进行比较。

我已经解决了程序中的两个问题,从而提供了解决方案。

matches = [
                {
                    "15477084": [1]
                },
                {
                    "360418": [2]
                },
                {
                    "15477084": [1]
                },
                {
                    "15477084": [3,4]
                }
            ]
            
            
new_matches = []

for j in matches:
    newdict = dict()
    for key,value in j.items():
        if len(new_matches) != 0:
            for k in new_matches:
                if key in k.keys():
                    for i in value:
                        if i not in k[key]:
                            k[key].append(i)
                    break

                else:
                    newdict[key] = value
                    new_matches.append(newdict)                 
        else:
            newdict[key] = value
            new_matches.append(newdict)

print(new_matches)