如果包含相同的字符串python,则比较同一个dict中的键

时间:2017-09-07 14:34:30

标签: python dictionary iteration

我有一个带有很多键的字典,这些键有大约100个值。 但是每个dict最后都有某种ID,我需要将每个dict的值与一些引用进行比较,但只要它们具有相同的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 id,以及我需要改变的东西都要做。 objDict是我的对象dict,refd是带有引用对象的dict,让我们从上面的例子中获取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。如果只有一个ref用于所有对象,无论bbc id是什么,这段代码都能正常工作。

1 个答案:

答案 0 :(得分:0)

要“将具有相同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]})

我们可以看到两种情况下的结果都已正确分组。请注意,您可以对可以使用dict的任何内容使用defaultdict - 它仅用于在满足新密钥时创建列表。

如果您无法访问数据源,则必须执行此类操作。但是,如果你可以改变它,像嵌套字典/列表(因为索引是连续的)会让你的生活更轻松。