比较特定领域的两个词典列表

时间:2018-11-21 12:04:34

标签: python list dictionary

我有两个包含字典的列表。我想比较每个词典中的某些字段。

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

7 个答案:

答案 0 :(得分:2)

我不知道我是否完全理解您的问题,但我认为以下代码可以解决问题:

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迭代。使用另一个列表,您可以指定要比较的字段。在主循环中,您遍历可比较的字段并进行相应打印。

答案 1 :(得分:0)

您可以使用以下代码比较所有对应的字段:

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对象!

答案 2 :(得分:0)

我不了解您的数据结构的合理性,但我认为可以解决问题:

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

答案 3 :(得分:0)

如果您乐于使用第三方库,则可以通过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

答案 4 :(得分:0)

只需与此进行比较

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])

答案 5 :(得分:0)

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

答案 6 :(得分:0)

有人已经制作了一个名为deepdiff的模块,该模块可以完成此任务,而且还有更多功能!有关详细说明,请参见this answer

首先 -安装

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在您的项目上!