我有一个带有很多键的字典,这些键有大约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是什么,这段代码都能正常工作。
答案 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所讨论的许多混乱。
代码包含两种方法 - 它会根据您对数据的了解而改变。第一种方法将更有效率。代码只生成一个键列表,因为我不确定你想要用它们做什么 - 但是,这种方法仍然适用于你想对组进行的任何操作。
在这两种情况下,您都可以立即访问分组值(v
或data[...]
)并进行修改,或者追溯查看列表并执行更多操作。
这有以下输出:
{'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 - 它仅用于在满足新密钥时创建列表。
如果您无法访问数据源,则必须执行此类操作。但是,如果你可以改变它,像嵌套字典/列表(因为索引是连续的)会让你的生活更轻松。