下面的代码正在运行并带来了我想要的结果。但是,有两组两个字典理解,我无法将其转换为两个字典理解。这可能吗?
dicTfAll={1:{'c1': ['aa','bb','cc']},
2:{'c1': ['dd','ee','ff']}}
dicTf={1:{'c2': ['aax','bbx','cc']},
2:{'c2': ['ddy','eey','ff']},
3: {'c2': ['xx', '11']}}
allKeys=list(dicTfAll.keys())
dicTfAllP1={item[0]:item[1] for item in dicTf.items() if item[0] not in allKeys}
dicTfAllP2={item[0]:dict(dicTfAll[item[0]],**item[1]) for item in dicTf.items() if item[0] in allKeys}
dicTfAllP=dicTfAllP1
dicTfAllP.update(dicTfAllP2)
# I use at this point dicTfAllP to do a lot of calculations.
# dicTfAllP has the same form but very different values.
allKeys=list(dicTfAllP.keys())
listOfCompanies=['c1','c2']
outputCompanies={}
for company in listOfCompanies:
theKeys=[key for key in allKeys if company in dicTfAllP[key]]
outputCompanies[company]={token:key for key in theKeys for token in dicTfAllP[key][company]}
准确地说,我想将下面的这些行转换为一个字典理解[它生成一个嵌套字典,它是上述字典的合并]:
allKeys=list(dicTfAll.keys())
dicTfAllP1={item[0]:item[1] for item in dicTf.items() if item[0] not in allKeys}
dicTfAllP2={item[0]:dict(dicTfAll[item[0]],**item[1]) for item in dicTf.items() if item[0] in allKeys}
此外,我想将下面的这些行也转换为一个字典理解[它构建一个嵌套字典来恢复原始字典(合并之前)]:
outputCompanies={}
for company in listOfCompanies:
theKeys=[key for key in allKeys if company in dicTfAllP[key]]
outputCompanies[company]={token:key for key in theKeys for token in dicTfAllP[key][company]}
我特别担心执行的效率。如果我需要保留这种结构该怎么办? 我确实必须保留这个结构,因为我必须在两组字典理解之间进行大量计算。
最佳答案
推导式是 Python 的一个令人惊叹的功能,但它们并不总是最好的情况。与其创建大量变量并将它们混在一起,不如一次处理一个变量可能会更好。我确信可以从这段代码中榨取更多的汁液,但这应该提供可读性和处理能力的良好平衡。我检查了输出以确保它与您的代码的输出匹配。
dicTfAll = {
1: {'c1': ['aa', 'bb', 'cc']},
2: {'c1': ['dd', 'ee', 'ff']}
}
dicTf = {
1: {'c2': ['aax', 'bbx', 'cc']},
2: {'c2': ['ddy', 'eey', 'ff']},
3: {'c2': ['xx', '11']}
}
outputCompanies = {}
for d in [dicTfAll, dicTf]:
for idx, records in d.items():
for company, items in records.items():
if company not in outputCompanies.keys():
outputCompanies[company] = {}
for item in items:
outputCompanies[company][item] = idx
print(outputCompanies)
# {
# 'c2': {'11': 3, 'ddy': 2, 'eey': 2, 'cc': 1, 'xx': 3, 'ff': 2, 'bbx': 1, 'aax': 1},
# 'c1': {'aa': 1, 'bb': 1, 'cc': 1, 'dd': 2, 'ee': 2, 'ff': 2}
# }
由于您正在寻找性能更高的代码,因此这里是使用 %%timeit
的运行时比较在 jupyter 实验室。
# My version
2.99 µs ± 30 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
# Original Version
6.39 µs ± 25.3 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
我还尝试了稍微更紧凑的代码版本,但最终运行时间更长。
%%timeit
outputCompanies = defaultdict(dict)
for d in [dicTfAll, dicTf]:
for idx, records in d.items():
for company, items in records.items():
outputCompanies[company].update({item: idx for item in items})
# 4.88 µs ± 22.7 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
另一个实际上包含理解的测试:
%%timeit
outputCompanies = {}
for d in [dicTfAll, dicTf]:
for idx, records in d.items():
for company, items in records.items():
if company not in outputCompanies.keys():
outputCompanies[company] = {}
outputCompanies[company].update({
item: idx for item in items
})
# 4.99 µs ± 23.3 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
对于您的代码的一些评论,dict.keys()
返回 list
对象,因此无需调用 list(dict.keys())
。也无需创建变量 allKeys
因为您可以调用 dict.keys()
在你的字典理解中。公司是硬编码的,如果这是一次性脚本,那么这很好,但如果您希望数据集随着时间的推移而扩展,则不是最好的。但如果您想对它们进行硬编码,您可以跳过变量声明并只需输入 for company in ['c1','c2']:
。接下来,您可以通过创建 dicTfAllP
来保存更多变量等于第一个理解,然后用第二个理解更新它。将它们放在一起,您将得到以下代码。它更具可读性,也更容易理解,但性能并没有更高。
%%timeit
dicTfAllP = {
item[0]:item[1]
for item
in dicTf.items()
if item[0] not in dicTfAll.keys()
}
dicTfAllP.update({
item[0]: dict(dicTfAll[item[0]], **item[1])
for item
in dicTf.items()
if item[0] in dicTfAll.keys()
})
outputCompanies = {}
for company in ['c1','c2']:
theKeys = [key for key in dicTfAllP.keys() if company in dicTfAllP[key]]
outputCompanies[company] = {
token:key
for key in theKeys
for token in dicTfAllP[key][company]
}
# 6.11 µs ± 58.2 ns per loop (mean ± std. dev. of 7 runs, 100000 loops each)
关于python - 如何简化这些字典理解?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/59807223/