2017-09-07 115 views
-2

我有一個與許多鍵和大約100個值這些鍵的字典。 但是每個字典在最後都有某種ID,我需要比較每個字典的值與一些引用,但只是它們具有相同的ID。 例如,鍵:如果包含相同的字符串比較相同的字符串鍵python

{'mmc-1/bbc-1': { 
'inner_key1' : '1', 
'inner_key2' : '4', 
'inner_key3' : '3', 
'inner_key4' : '5', 
'inner_key5' : '4', 
'inner_key6' : '5', 
'inner_key7' : '2', 
'inner_key8' : '0', 
'inner_key9' : '10'}, 
'mmc-1/bbc-2': { 
'inner_key1' : '3', 
'inner_key2' : '4', 
'inner_key3' : '3', 
'inner_key4' : '5', 
'inner_key5' : '6', 
'inner_key6' : '5', 
'inner_key7' : '2', 
'inner_key8' : '8', 
'inner_key9' : '10'}, 
... 
'mmc-2/bbc-1': { 
'inner_key1' : '1', 
'inner_key2' : '4', 
'inner_key3' : '3', 
'inner_key4' : '5', 
'inner_key5' : '7', 
'inner_key6' : '5', 
'inner_key7' : '2', 
'inner_key8' : '0', 
'inner_key9' : '10'}} 

所以我需要比較剛剛MMC-1/BBC-1使用MMC-2/BBC-1和MMC-3/BBC-1,因此,BBC ID是一個條件。請記住,這些是字典的關鍵。 我可以

.split('/')[1].split('-')[1] 

開口鍵,但不知道如何使一個條件比較只是與同BBC字典。 這是比較並將差異放入新字典中的代碼,但是對於每個密鑰都是這樣做的,不需要改動bbc id,這就是我需要改變的地方。 objDict是我的對象字典,refd是帶引用對象的字典,讓我們從上面的例子中爲ref對象取第一個對象。

#Choose reference object 
ref = tempdict['mmc-1/bbc-1'] 
m_dif = {} 

#Main function for finding differences 
for obj, objDict in tempdict.iteritems(): 
    currentDict = {} 

    # Check if the keys match. 
    if objDict.keys() != ref.keys(): 
     for key in ref: 
      if key not in objDict.keys(): 
       currentDict[key] = None 

     for key in objDict: 
      if key not in ref.keys(): 
       # Store unexpected values in object. 
       currentDict[key] = None 

    # Check if values are the same. 
    for k, v in objDict.iteritems(): 
     # Check if the key is in ref to avoid error 
     if k in ref: 
      # Then compare if values are equal 
      if ref[k] != objDict[k]: 
       # Make actual diff 
       currentDict[k] = v 
    # Store differences for current object against object title. 
    m_dif[obj] = currentDict 

我知道這不是一個很好解釋的問題,但讓我知道什麼是混亂,我要解釋。

讓我們假設基準是MMC-1/BBC-1與BBC ID = 1 所需的輸出對象:

{'mmc-2/bbc-1': { 
'inner_key5' : '7'}} 

而對於所有其他BBC ID同樣的事情。如果只有一個ref的所有對象,無論bbc id是什麼,此代碼完美工作。

+1

如果您提供了每個相關對象的子樣本,這將非常有用 - 真正向我們展示您的所有「dict」或其他任何類似於Python語法的東西(我目前不完全清楚哪些位是關鍵字或什麼的價值)。然後提供一個輸出應該是什麼樣的小樣本(以及你正在努力做什麼)。與使用不熟悉的術語相比,這通常是交流問題的一種更簡單的方法。 –

+0

@IzaakvanDongen我編輯了一下我的問題。 – jovicbg

+0

給我們一些可以顯示你的問題的runnable(並且最好把問題放大回來,這裏似乎有更多的細節與你的真實問題無關......) – thebjorn

回答

0

要「組一起與同BBC值鍵」(這是你的問題我的工作解釋),有幾件事情你可以做:

import pprint 

from collections import defaultdict 

max_mmc = 10 
max_bbc = 3 

data = {"mmc-{}/bbc-{}".format(a, b): a * 10 ** b for a in range(max_mmc) 
                for b in range(max_bbc)} 

pprint.pprint(data) 

# approach where you already know the maximum id of bbc and mmc 

result_1 = {"bbc-{}".format(bbc): [data["mmc-{}/bbc-{}".format(mmc, bbc)] 
            for mmc in range(max_mmc)] 
            for bbc in range(max_bbc)} 

# approach where you don't know the maximums 

result_2 = defaultdict(list) 

for k, v in data.items(): # items because of Python 3 
    mmc, bbc = k.split("/") 
    result_2[bbc].append(v) 

pprint.pprint(result_1) 
pprint.pprint(result_2) 

在這裏,我一個漂亮的加入簡短的臨界PEP-8兼容數據模型 - 您的密鑰的一個子集被重新創建,每個值都是mmc和bbc的粗略「散列」版本。這讓我們以後可以看到它已正常工作。 (即根據bbc-2分組應產生100的所有倍數)。它也消除了比約恩談論的許多混亂。

該代碼包含兩種方法 - 它將根據您對數據的瞭解程度而改變。第一種方法將會更有效率。該代碼只是產生一個鍵列表,因爲我不確定你想要如何處理它們 - 但是,這種方法仍然適用於你想對組進行任何操作。

在這兩種情況下,您都可以立即訪問分組值(vdata[...])並對其進行修改,或追溯性地通過列表並執行一些操作。

這有以下的輸出:

{'mmc-0/bbc-0': 0, 
'mmc-0/bbc-1': 0, 
'mmc-0/bbc-2': 0, 
'mmc-1/bbc-0': 1, 
'mmc-1/bbc-1': 10, 
'mmc-1/bbc-2': 100, 
'mmc-2/bbc-0': 2, 
'mmc-2/bbc-1': 20, 
'mmc-2/bbc-2': 200, 
'mmc-3/bbc-0': 3, 
'mmc-3/bbc-1': 30, 
'mmc-3/bbc-2': 300, 
'mmc-4/bbc-0': 4, 
'mmc-4/bbc-1': 40, 
'mmc-4/bbc-2': 400, 
'mmc-5/bbc-0': 5, 
'mmc-5/bbc-1': 50, 
'mmc-5/bbc-2': 500, 
'mmc-6/bbc-0': 6, 
'mmc-6/bbc-1': 60, 
'mmc-6/bbc-2': 600, 
'mmc-7/bbc-0': 7, 
'mmc-7/bbc-1': 70, 
'mmc-7/bbc-2': 700, 
'mmc-8/bbc-0': 8, 
'mmc-8/bbc-1': 80, 
'mmc-8/bbc-2': 800, 
'mmc-9/bbc-0': 9, 
'mmc-9/bbc-1': 90, 
'mmc-9/bbc-2': 900} 

{'bbc-0': [0, 1, 2, 3, 4, 5, 6, 7, 8, 9], 
'bbc-1': [0, 10, 20, 30, 40, 50, 60, 70, 80, 90], 
'bbc-2': [0, 100, 200, 300, 400, 500, 600, 700, 800, 900]} 

defaultdict(<class 'list'>, 
      {'bbc-0': [0, 1, 2, 3, 4, 5, 6, 7, 8, 9], 
      'bbc-1': [0, 10, 20, 30, 40, 50, 60, 70, 80, 90], 
      'bbc-2': [0, 100, 200, 300, 400, 500, 600, 700, 800, 900]}) 

我們可以看到,結果在這兩種情況下被正確分組。請注意,對於任何可以使用字典的任何東西,您都可以使用defaultdict--它僅用於在滿足新密鑰時創建列表。

如果您無法訪問數據源,則必須執行此操作。但是,如果你可以改變它,像嵌套字典/列表(因爲索引是連續的)會讓你的生活變得更容易。

相關問題