【问题标题】:Python dictionary comparasionPython字典比较
【发布时间】:2017-04-17 12:55:22
【问题描述】:

我把一个字典变成了一个字典,看起来像这样:第一个外部字典的键是对象,内部字典的键是对象的参数。一个对象是引用,我需要将所有对象的所有参数的值与那个引用对象进行比较,如果有差异则打印它,如果没有差异,则什么也不做。字典看起来像这样:

{'object-1301': {'act1': 'false',
  'act1x': 'true',
  'act': 'false',
  'actAdv': 'false',
  'actAe': 'false',
  'actArp': 'false',},
 'object-218': {'act1': 'true',
  'act1x': 'false',
  'act': 'false',
  'actAdv': 'false',
  'actAe': 'true',
  'actArt': 'false',}, 
...
 }

我到目前为止的代码是,其中 ref 是引用对象,dict 是我在上面复制的 dict:

main_dif = {}
for key, value in dict.iteritems():
    dif_k = {}
    for k, v in value.iteritems():
        try: 
            a = ref[k]
        except:
             a = None
        if a != v:
                dif_k.update({k:v})
    main_dif.update({key:dif_k})

我遇到的问题是下一个:当引用对象根本没有某些参数,但其他一些对象有,这很好用,但是当引用对象有而其他对象没有时,什么都没有发生,可以没找到。

【问题讨论】:

  • 也许您可以先更新一下您的问题。您在示例的第一行中缺少重音。您也可以用ref.get(k,None) 替换try/except 构造。最后,语法需要注意一下。
  • @Tom de Geus 我已经编辑了我的问题。我没有错过任何一排,你为什么这么认为?
  • 你想做什么以及想要的结果?
  • 在你的字典中,act1 缺少一些东西 --> 'act1':
  • 如我所说,将所有对象的参数值与参考对象进行比较。如果有差异,请打印(稍后在 excel 文件中)。第一行(标题下方)是引用对象的值,下面是所有其他对象及其值(与引用不同)。也许我可以在下午给你发一张 excel 例子的截图? @manvi77

标签: python dictionary iteration


【解决方案1】:

这里有一个更详细的答案。看看这是否适合您检查键和值。

from pprint import pprint

# Use your own ref, I've just this one all to true for testing.
ref = {
    'act1': 'true',
    'act1x': 'true',
    'act': 'true',
    'actAdv': 'true',
    'actAe': 'true',
    'actArp': 'true',
    }

data = {
    'object-1301': {
        'act1': 'false',
        'act1x': 'true',
        'act': 'false',
        'actAdv': 'false',
        'actAe': 'false',
        'actArp': 'false',
    },
    'object-218': {
        'act1': 'true',
        'act1x': 'false',
        'act': 'false',
        'actAdv': 'false',
        'actAe': 'true',
        'actArt': 'false',
    },
    'object-short': {
        'act1': 'false'
        },
    'object-extra-keys': {
        'act1': 'true',
        'act1x': 'true',
        'act': 'true',
        'actAdv': 'true',
        'actAe': 'true',
        'actArp': 'true',
        'extra': 'true',
    },
    'object-as-ref': {
        'act1': 'true',
        'act1x': 'true',
        'act': 'true',
        'actAdv': 'true',
        'actAe': 'true',
        'actArp': 'true',
        },
    'object-opposite-to-ref': {
        'act1': 'false',
        'act1x': 'false',
        'act': 'false',
        'actAdv': 'false',
        'actAe': 'false',
        'actArp': 'false',
    }
 }

mainDiff = {}

for obj, objDict in data.iteritems():
    currentDict = {}

    # Check if the keys match. 
    if objDict.keys() != ref.keys():
        for key in ref:
            if key not in objDict.keys():
              # Store keys missing from object.
              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]:
                # Then store actual value
                currentDict[k] = v
    # Store differences for current object against object title.
    mainDiff[obj] = currentDict

print 'Differences:'
pprint(mainDiff)

【讨论】:

  • 如果您希望在打印时使用更具描述性的内容,可以将 None 替换为“缺失”或“额外”。
  • 问题是我有大约 3000 个对象,300-400 个参数,我只复制了一小块。请稍等
  • 哦,这有点工作,但我只需要几分钟就可以确定。
【解决方案2】:

我知道如何检查引用对象,但引用对象可能有其他键。

所以我会添加一个测试来检查密钥是否相同。我在这里打印,但您可以将其记录到字典或错误列表中。

main_dif = {}
for key, value in dict.iteritems():
    dif_k = {}

    if value.keys() != ref.keys():
        print('Key mismatch for {0}'.format(key))
        print('Ref: {0}.  Actual: {1}'.format(ref.keys(), value.keys()) 

    for k, v in value.iteritems():
        try: 
            a = ref[k]
        except:
             a = None
        if a != v:
                dif_k.update({k:v})
    main_dif.update({key:dif_k})

如果将两个列表转换为集合,然后将它们相减,则可以更好地计算额外或缺失的键。

【讨论】:

  • 引用对象可以有其他键(参数)。这才是重点。如果有一些其他对象没有的键,打印它并添加到其他对象值:'None'。这在相反的情况下工作,如果其他对象有一些键,什么引用没有它打印该参数的值和添加值:'没有引用 obj。当然,如果两个对象都有相同的键,我需要比较它们的值。 @MichaelAshleyCurrin
  • 我得到了这个:for k, v in value.iteritems(): ^ SyntaxError: invalid syntax 我不知道为什么
  • 请看我的最新回答。
【解决方案3】:

你可以这样试试:

In [17]: refdict
Out[17]: 
{'object-1301': {'act': 'false',
  'act1': 'false',
  'act1x': 'true',
  'actAdv': 'false',
  'actAe': 'false',
  'actArp': 'false'}}

In [18]: mydict
Out[18]: 
{'object-218': {'act': 'false',
  'act1': 'true',
  'act1x': 'false',
  'actAdv': 'false',
  'actAe': 'true',
  'actArt': 'false'}}

for k, v in refdict.iteritems():
    for k1, v1 in mydict.iteritems():
        if k != k1:
            print('Checking for object: {0}'.format(k1))
            for k2, v2 in v.iteritems():
                if k2 in v1:
                    if v[k2] == v1[k2]:
                        continue
                    else:
                        print "Differences"
                        print('For Key {0}, Value {1} are different'.format(k2, v1[k2]))
                else:
                    print "Missing key in current object"
                    print k2
            for k3 in v1:
                if k3 not in v:
                    print "Missing key in reference object"
                    print k3

#result
Checking for object: object-218
Differences
For Key act1, Value true are different
Differences
For Key actAe, Value true are different
Missing key in current object
actArp
Differences
For Key act1x, Value false are different
Missing key in reference object
actArt

【讨论】:

    猜你喜欢
    • 2019-06-15
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多