【问题标题】:Compare keys from the same dict if contain same string python如果包含相同的字符串 python 比较来自相同字典的键
【发布时间】:2017-09-07 14:34:29
【问题描述】:

我有一个包含很多键和大约 100 个值的字典。 但是每个字典最后都有某种ID,我需要将每个字典的值与一些参考进行比较,但前提是它们具有相同的ID。 例如键:

{'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 是一个条件。 请记住,这些是 dict 的键。 我可以用

拆分键
.split('/')[1].split('-')[1]

但是不知道如何为仅 dict 与同一个 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

我知道这不是一个很好解释的问题,但让我知道有什么令人困惑的地方,我会解释一下。

假设 bbc id = 1 的对象的引用是 mmc-1/bbc-1。 期望的输出:

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

对于所有其他 bbc id 也是如此。如果所有对象都只有一个引用,则此代码可以完美运行,无论 bbc id 是什么。

【问题讨论】:

  • 如果您提供每个相关对象的子样本,这将很有用 - 真正向我们展示您的所有 dicts 或 Python 语法中的其他内容(我目前并不完全清楚哪些位是什么的键或值)。然后提供一个输出应该是什么样子的小样本(以及你正在努力做的事情)。与使用不熟悉的术语相比,这通常是一种更简单的沟通问题的方式。
  • @IzaakvanDongen 我稍微编辑了我的问题。
  • 给我们一些可运行的东西来显示您的问题(最好将问题缩小,这里似乎有更多与您的实际问题无关的细节......)
  • @thebjorn 但我没有更多细节,真的。我已经解析了 xml 文件并在 dict 中得到了 dict。现在我需要将一个外部键的内部键值与另一个外部键值进行比较,如果它们具有相同的 bbc id。当然,还有更多的键,但这里不需要键入。您也许可以尝试使用这三个键和该代码运行脚本,看看我已经拥有什么以及如何进行必要的更改。
  • 所以你的目标只是找到从 0 到 ~100 的所有 "mmc-i/bbc-1" 的所有键 i?还是我误会了你?

标签: python dictionary iteration


【解决方案1】:

要“将具有相同 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 的所有倍数)。它还消除了 thebjorn 所说的很多混乱。

代码包含两种方法 - 它会根据您对数据的了解程度而改变。第一种方法会更有效率。该代码仅生成一个键列表,因为我不确定您想对它们做什么 - 但是,这种方法仍然适用于您想要对组执行的任何操作。

在这两种情况下,您都可以立即访问分组值(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 用于任何可以使用 dict 的内容 - 它仅用于在遇到新键时创建列表。

如果您无权访问您的数据源,则必须这样做。但是,如果您完全可以更改它,嵌套字典/列表(因为索引是连续的)之类的东西会让您的生活更轻松。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-11-29
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2022-10-15
    • 2016-12-05
    • 2016-04-05
    • 2016-12-18
    相关资源
    最近更新 更多