如何从具有多个对象的python字典中获取重复对象的总数和相应的键?

2024-03-29 06:41:37 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个python字典,它由许多嵌套字典组成。也就是说,它看起来像这样:

result = {
    123: {
       'route1': 'abc'
       'route2': 'abc1'
        },
    456: {
       'route1': 'abc'
       'route2': 'abc1'
        },
    789: {
       'route1': 'abc2'
       'route2': 'abc3'
        },
    101: {
       'route1': 'abc'
       'route2': 'abc1'
        },
    102: {
       'route1': 'ab4'
       'route2': 'abc5'
        }

}

这里我们可以看到123456101具有相同的值。 我要做的是找出重复的物体,在这种情况下是:

{
   'route1': 'abc'
    'route2': 'abc1'
 }

以及具有这个重复对象的键,即123456101。 我们怎么做?你知道吗

除了重复对象信息,我还想知道哪些对象不重复。即789及其相应的对象和102及其相应的对象。你知道吗

PS:请注意,我事先并不知道哪些对象是重复的,因为这个结构将在代码中生成。因此,可能不存在任何重复的对象,或者可能存在多个对象,即多个对象。 另外,由于一些限制,我不能使用pandasnumpy等。你知道吗


Tags: 对象信息字典情况result物体psabc
3条回答

可以通过创建一个字典来实现这一点,其中包含resultdict中每个不同值的所有匹配键(其中值本身就是dict)。这是Python中相当常见的模式,遍历一个容器并将值聚合到dict中。然后,一旦创建了聚合dict,就可以将其拆分为重复值和单个值。你知道吗

要构建聚合dict,需要使用result中的每个子目录作为键,并将原始dict中匹配的键附加到与该子目录相关联的列表中。挑战在于不能将子目录直接用作字典键,因为它们是不可散列的。但是你可以通过把它们转换成元组来解决这个问题。元组也应该被排序,以避免丢失的重复项以不同的顺序出现。你知道吗

只需看一些示例代码,可能更容易理解:

result = {
    123: {'route1': 'abc', 'route2': 'abc1'},
    456: {'route1': 'abc', 'route2': 'abc1'},
    789: {'route1': 'abc2', 'route2': 'abc3'},
    101: {'route1': 'abc', 'route2': 'abc1'},
    102: {'route1': 'ab4', 'route2': 'abc5'}
}

# make a dict showing all the keys that match each subdict
cross_refs = dict()
for key, subdict in result.items():
    # make hashable version of subdict (can't use dict as lookup key)
    subdict_tuple = tuple(sorted(subdict.items()))
    # create an empty list of keys that match this val
    # (if needed), or retrieve existing list
    matching_keys = cross_refs.setdefault(subdict_tuple, [])
    # add this item to the list
    matching_keys.append(key)

# make lists of duplicates and non-duplicates
dups = {}
singles = {}
for subdict_tuple, keys in cross_refs.items():
    # convert hashed value back to a dict
    subdict = dict(subdict_tuple)
    if len(keys) > 1:
        # convert the list of matching keys to a tuple and use as the key
        dups[tuple(keys)] = subdict
    else:
        # there's only one matching key, so use that as the key
        singles[keys[0]] = subdict

print(dups)
# {
#     (456, 123, 101): {'route2': 'abc1', 'route1': 'abc'}
# }
print(singles)
# {
#     789: {'route2': 'abc3', 'route1': 'abc2'}, 
#     102: {'route2': 'abc5', 'route1': 'ab4'}
# }

您可以使用drop_duplicates()pandas函数:

首先在数据帧上转换你的dict

import pandas as pd `

df = pd.DataFrame(result).T

输出:

    route1  route2
123 abc     abc1
456 abc     abc1
789 abc2    abc3
101 abc     abc1
102 ab4     abc5

然后使用函数drop_duplicates并转换为dict

df2 = df1.drop_duplicates(subset=['route1', 'route2']).T.to_dict()

输出:

{
 123: {
       'route1': 'abc', 
       'route2': 'abc1'
      },
 789: {
       'route1': 'abc2',
       'route2': 'abc3'
      },
 102: {
       'route1': 'ab4', 
       'route2': 'abc5'
      }
}

使用collections.defaultdict

from collections import defaultdict

d = defaultdict(list)
for k, v in result.items():
    d[tuple(v.items())].append(k)

desired = {
   'route1': 'abc',
    'route2': 'abc1'
 }
d[tuple(desired.items())]

输出:

[456, 123, 101]

对于不重复的项目,请使用列表理解:

[v for v in d.values() if len(v) == 1]

输出:

[[102], [789]]

相关问题 更多 >