簡體   English   中英

比較特定字段的兩個字典列表

[英]compare two lists of dictionaries for specific fields

我有兩個包含字典的列表。 我想比較每個詞典中的某些字段。

current_list = [{"name": "Bill","address": "Home", "age": 23, "accesstime":11:14:01}, 
            {"name": "Fred","address": "Home", "age": 26, "accesstime":11:57:43},
            {"name": "Nora","address": "Home", "age": 33, "accesstime":11:24:14}]

backup_list = [{"name": "Bill","address": "Home", "age": 23, "accesstime":13:34:24}, 
           {"name": "Fred","address": "Home", "age": 26, "accesstime":13:34:26},
           {"name": "Nora","address": "Home", "age": 33, "accesstime":13:35:14}]

列表/詞典應該按順序相同,我只想比較某些鍵值對。 像名稱,地址,年齡和忽略訪問時間,但我到目前為止比較每個鍵/對。 所以我只想比較一下

current_list:dictionary[0][name] -> backup_list:dictionary[0][name] and then 
current_list:dictionary[0][address] -> backup_list:dictionary[0][address] 

等等。

for x in current_list:
    for y in backup_list:
        for k, v in x.items():
            for kk, vv in y.items():
                if k == kk:
                    print("Match: {0}".format(kk))
                    break
                elif k != kk:
                    print("No match: {0}".format(kk))

電流輸出

Match name with name
No Match address with name
Match address with address
No Match age with name
No Match age with address
Match age with age
No Match dateRegistered with name
No Match dateRegistered with address
No Match dateRegistered with age
Match dateRegistered with dateRegistered

首選輸出

Match name with name
Match address with address
Match age with age

*由於需求更改,我的列表成為Elementtree xml元素的列表*

因此,而不是上面的列表,它變成了

backup_list =  ["<Element 'New' at 0x0000000002698C28>, <Element 'Update' at 0x0000000002698CC8>, <Element 'New' at 0x0000000002698CC8>"]

ElementTree是一個包含以下內容的xml元素:

{"name": "Nora", "address": "Home", "age": 33, "dateRegistered": 20140812}"

所以這個基於下面的答案似乎滿足我的要求到目前為止:

value_to_compare = ["name", "address", "age"]
for i, elem in enumerate(current_list):
    backup_dict = backup_list[i]
    if elem.tag == "New":
        for key in value_to_compare:
            try:
                print("Match {0} {1} == {2}:".format(key, backup_dict.attrib[key], elem.attrib[key]))
            except KeyError:
                print("key {} not found".format(key))
            except:
                raise
    else:
        continue

我不知道我是否完全理解你的問題,但我認為以下代碼應該可以解決問題:

compare_arguments = ["name", "age", "address"]
for cl, bl in zip(current_list, backup_list):
    for ca in compare_arguments:
        if cl[ca] == bl[ca]:
            print("Match {0} with {0}".format(cl[ca]))
    print("-" * 10)

在上面的代碼中完成的是對兩個列表的zip迭代。 使用另一個列表,您可以指定要比較的字段。 在主循環中,您遍歷可比較的字段並相應地打印它們。

您可以使用以下代碼比較所有相應的字段:

for dct1, dct2 in zip(current_list, backup_list):
    for k, v in dct1.items():
        if k == "accesstime":
            continue
        if v == dct2[k]:
            print("Match: {0} with {0}".format(k))
        else:
            print("No match: {0} with {0}".format(k))

請注意, "accesstime"鍵的值不是有效的Python對象!

我不明白你的數據結構的合理性,但我認為這樣做可以解決問題:

value_to_compare = ["name", "address", "age"]

for i, elem in enumerate(current_list):
    backup_dict = backup_list[i]
    for key in value_to_compare:
        try:
            print("Match {}: {} with {}".format(key, elem[key], backup_dict[key]))
        except KeyError:
            print("key {} not found".format(key))
            # may be a raise here.
        except:
            raise

如果您樂意使用第三方庫,可以通過Pandas以更有條理的方式更有效地實施此類任務:

import pandas as pd

res = pd.merge(pd.DataFrame(current_list),
               pd.DataFrame(backup_list),
               on=['name', 'address', 'age'],
               how='outer',
               indicator=True)

print(res)

  accesstime_x address  age  name accesstime_y _merge
0     11:14:01    Home   23  Bill     13:34:24   both
1     11:57:43    Home   26  Fred     13:34:26   both
2     11:24:14    Home   33  Nora     13:35:14   both

結果_merge = 'both'為每行顯示的組合['name', 'address', 'age']發生在兩個列表,但是,除此之外,你能看到accesstime每個輸入。

只需與此比較 -

for current in current_list:
    for backup in backup_list:
        for a in backup:
            for b in current:
                if a == b:
                    if a == "name" or a== "age" or a== "address" :
                        if backup[a] == current[b]:
                            print (backup[a])
                            print (current[b])

您可以使用zip方法同時迭代列表。

elements_to_compare = ["name", "age", "address"]
for dic1, dic2 in zip(current_list, backup_list):
    for element in elements_to_compare :
        if dic1[element] == dic2[element]:
            print("Match {0} with {0}".format(element))

有人已經制作了一個名為deepdiff的模塊,可以做到這一點,而且還有更多! 請參閱此答案以獲取詳細說明!

首先 - 安裝它

pip install deepdiff

然后 - 享受

#of course import it
from deepdiff import DeepDiff

current_list, backup_list = [...], [...] #values stated in question.

for c, b in zip(current_list, backup_list):
    dif = DeepDiff(c, b)
    for key in ["name", "age", "address"]:
        try:
            assert dif['values_changed'][f"root['{key}'"]
            #pass the below line to exclude any non-matching values like your desired output has
            print(f"No Match {key} with {key}")
        except KeyError:
            print(f"Match {key} with {key}")

結果: - 如預期的那樣

Match name with name
Match address with address
Match age with age
Match name with name
Match address with address
Match age with age
Match name with name
Match address with address
Match age with age

最后的說明

此模塊還有許多其他功能,例如type更改, key更改/刪除/添加,廣泛的text比較和搜索。 絕對值得一看。

~GL你的項目!

暫無
暫無

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

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