簡體   English   中英

如何比較字典列表中的多個鍵值?

[英]How do I compare multiple key values from a list of dictionaries?

我有一個字典列表,列表中的所有字典都具有相同的結構。 例如:

test_data = [{'id':1, 'value':'one'}, {'id':2, 'value':'two'}, {'id':3, 'value':'three'}]

我需要做的是比較這些詞典中的每一個並返回基於值鍵對的“相似”詞典。 例如,給定的關鍵value和值oen ,我想找到幾乎相同的所有匹配的詞典oen在這種情況下將是[{'id':1, 'value':'one'}]

difflib有一個函數get_close_matches ,它接近我需要的函數。 我能夠使用列表推導提取特定鍵的值,然后將這些值與我的搜索進行比較:

values = [ item['value'] for item in test_data ]
found_vals = get_close_matches('oen', values) #returns ['one']

我需要做的是更進一步,將所有內容與原始詞典重新組合在一起:

In  [1]: get_close_dicts('oen', test_data, 'value')
Out [1]: [{'id':1, 'value':'one'}]

注意:字典列表非常大,因此我希望盡可能高效/快速。

您可以在對數據運行get_close_dicts之前創建反向查找dict,這樣一旦返回了一組值,就可以使用它們來查找相關的dict(s)。

如果你保證在你的dicts中為'value'鍵提供唯一值,那么你可以這樣做:

reverselookup = {thedict['value']:thedict for thedict in test_data}

但是,如果您需要處理多個dicts對'value'鍵具有相同值的情況,那么您需要映射所有這些(這將為您提供一個dict,其中鍵是'value'中的值並且值是具有該值的dicts列表):

from collections import defaultdict
reverselookup = defaultdict(list)
for testdict in test_data:
    reverselookup[testdict['value']].append(testdict)

例如,如果你的測試數據中有一個額外的dict,就像這樣:

>>> test_data = [{'id':1, 'value':'one'}, {'id':2, 'value':'two'}, 
                 {'id':3, 'value':'three'}, {'id':4, 'value':'three'}]

然后上面的反向查找結構會給你這樣的:

{
  "three": [
    {
      "id": 3,
      "value": "three"
    },
    {
      "id": 4,
      "value": "three"
    }
  ],
  "two": [
    {
      "id": 2,
      "value": "two"
    }
  ],
  "one": [
    {
      "id": 1,
      "value": "one"
    }
  ]
}

然后在獲得值之后,只需檢索dicts(如果您有列表用例,則可以鏈接,如果您有第一個用例,則無需鏈接):

from itertools import chain    
chain(*[reverselookup[val] for val in found_vals])

你可以:

return [d for d in test_data if get_close_matches('oen', [d['value'])]]

注意get_close_matches可能會返回多個結果。

無論如何,你最終會在某個時刻迭代每一本字典。 沒有解決這個問題。 您可以做的是在預處理階段完成所有工作,以便立即對函數進行實際調用。

正如ValAyal所提到的,反向查找字典在這里是一個好主意。 我正在想象一個字典value_dict ,其中key是第一個字典中的value ,該value包含完全匹配和類似value匹配。 d1d2為例,這些列表位於您要搜索的列表中。 如果

d1 = {'id':1, 'value':'one'}
d2 = {'id':3, 'value':'oen'}

然后:

value_dict["one"] = {"exact": [d1], "close": [d2]}
value_dict["oen"] = {"exact": [d2], "close": [d1]}

每當您插入具有已經看到的值的字典時,您可以立即確定所有完全匹配和近似匹配(僅通過查找該值),並相應地添加到各個列表。 如果您有一個之前未曾見過的新值,則必須將其與value_dict當前的所有值進行比較。 例如,如果要添加

d3 = {'id':5, 'value':'one'}

你會查找value_dict["one"]並獲得exact列表和close列表。 這些列表包含您需要修改的所有其他value_dict條目。 你需要增加的精確匹配one和結束比賽oen ; 您可以從返回的列表中獲取這兩個值。 你結束了

value_dict["one"] = {"exact": [d1, d3], "close": [d2]}
value_dict["oen"] = {"exact": [d2], "close": [d1, d3]}

所以一旦完成所有的預處理,你的函數就會變得更簡單:類似於get_close_dicts(val) (我不知道你的例子中第三個參數的作用)可以只return value_dict[val]["exact"] + value_dict[val]["close"] 你現在有一個能立即回答的功能。

預處理步驟非常復雜,但get_close_dicts的最終加速有望彌補它。 如果你想知道如何實現這一點,我可以在下班后再詳細說明。 希望這可以讓你對一個有用的數據結構有一個很好的想法,我並沒有駭人聽聞。

暫無
暫無

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

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