python - 使用组合迭代多个字典
问题描述
我有越来越多的 n_term 字典,其中的值E
需要以特定方式组合。字典具有以下形式:
one_terms = {'i': {'E':1},
'j': {'E':2},
...
'n': {'E':some_int}}
two_terms = {'i:j': {'E':12},
'i:k': {'E':13},
...
'm:n': {'E':some_int}}
three_terms = {'i:j:k': {'E':111},
'i:j:l': {'E':112},
...
'm:n:o': {'E':some_int}}
里面的数字是占位符。实际上,这些数字来自计算量大的计算。包含 n 项 (ijkl...n) 的字典的数量也可能会变得很大。例如,这可以达到五十个字典。
目的是将 n_term 字典的所有相应术语组合起来,并将该值附加到适当的字典中。一个例子更好地解释了这一点:
对于少量的术语(2 或 3),该任务相对简单,并且可以在没有调用组合的情况下完成。例如,对于 two_term 字典:
for key, value in two_terms.items():
i = one_terms[str(key).split(':')[0]]['E']
j = one_terms[str(key).split(':')[1]]['E']
ij = 0 -i -j
two_terms[key]['new_value'] = ij
给出我想要的解决方案。而对于three_terms 字典。
for key, value in three_terms.items():
i = one_terms[str(key).split(':')[0]]['E']
j = one_terms[str(key).split(':')[1]]['E']
k = one_terms[str(key).split(':')[2]]['E']
ij = two_terms[(str(key).split(':')[0] + ':' + two_terms[(str(key).split(':')[1])]['E']
ik = two_terms[(str(key).split(':')[0] + ':' + two_terms[(str(key).split(':')[2])]['E']
jk = two_terms[(str(key).split(':')[1] + ':' + two_terms[(str(key).split(':')[2])]['E']
ijk = 0 -ij -ik -jk -i -j -k
three_terms[key]['new_value'] = ijk
也给出了所需的解决方案。请注意,我已经使用该split()
功能来处理不同的组合键(ij、ik 等)。
然而,对于越来越多的 n_terms,这种方法变得不切实际。我需要一个迭代解决方案。
我的尝试。
我试图使用该itertools.combinations
库,以便可以迭代地遍历所有组合。
for C in range(1, len(dictionary):
for S in itertools.combinations(dictionary, C):
然而,这只是提供了一个元组,它变得难以操作成某种形式
n = n_terms[(str(key).split(':')[A] + ':' +\
str(key).split(':')[B] + ':' +\
...
str(key).split(':')[Z])]['E']
哪里A, B,...Z
会有组合。
在 中two_term case
,解决方案可能采用以下形式:
for key, value in two_term.items():
n_list
for i in range (0, 2):
n_list.append(one_terms[str(key).split(':')[i]])
two_body[key]['E'] = sum(n_list)
虽然我正在努力扩展这种方法。
解决方案
如果您有大量(甚至可变)这些 n-term 字典,最好将它们存储在单独的数据结构中,例如列表索引引用 n-term 中的“n”的列表:
terms = [
None, # zero terms (placeholder to align the n-term index later on)
{'i': {'E': 1}, 'j': {'E': 2}, 'k': {'E': 3}}, # one terms
{'i:j': {'E': 12}, 'i:k': {'E': 13}, 'j:k': {'E': 14}}, # two terms
{'i:j:k': {'E': 111}} # three terms
# and so on
]
然后,您可以遍历这些字典,并且对于每个 n-terms 字典,您可以为每个 r-terms 字典构建键组合,其中r < n
:
import itertools as it
for n in range(2, len(terms)):
for key in terms[n]:
new_value = 0
parts = key.split(':')
for r in range(1, n):
new_value -= sum(terms[r][':'.join(x)]['E'] for x in it.combinations(parts, r=r))
terms[n][key]['new_value'] = new_value
推荐阅读
- html - 获取 HTML 标记内的值 - 需要在里面的文本标签
- javascript - 寻找可能的目的地给出值列表
- angular - 角度区分多个树节点
- ios - 类型“NSNotification.Name”没有成员“UITextField”
- java - Makefile 不工作:make:Nothing to be done for `all'
- bash - 我如何在 bash 中捕获 gitlab-runner 的输出
- python - 根据列值删除行 - 但不仅仅是一个列值 - 值列表
- dart - Flutter 按状态对 JSON 进行排序
- javascript - 窗口卸载时提交表单
- ios - Nativescript Angular