首页 > 解决方案 > 使用组合迭代多个字典

问题描述

我有越来越多的 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)

虽然我正在努力扩展这种方法。

标签: pythondictionary

解决方案


如果您有大量(甚至可变)这些 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

推荐阅读