簡體   English   中英

如何從具有多個對象的python字典中獲取重復對象和相應鍵的總數?

[英]How to get total number of repeated objects and respective keys from a python dictionary having multiple objects?

我有一個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等。

使用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]]

您可以使用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'
      }
}

您可以通過創建一個字典來完成此操作,該字典包含result字典中每個不同值的所有匹配鍵(其中值本身就是dicts)。 這是Python中相當常見的模式,迭代一個容器並將值聚合到一個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'}
# }

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM