列出列表列表的复杂字典中的所有可能组合?

时间:2018-03-20 18:14:36

标签: python itertools

我有一个字典,其中包含字符串,None,列表和列表列表,如下例所示。

所需的结果是字典列表。字典的数量等于可能的总排列数。

要求是每个词典可能有None或值列表,但varVal有一个长度等于varName长度的列表列表(即,len(d['varVal'] = len(d['varName'])。

我认为已经处理了None问题并将varString保留为列表可以防止将字符串分解为字符。

到目前为止,虽然我的想法已经用尽了,但我已经搜索了许多溢出的帖子this one。任何帮助将不胜感激。谢谢。

示例

此示例生成所需结果:(

import itertools as it

d={}
d['varString']=['ExampleText']
d['n1']=[1,100]
d['n2']=None
d['varName']=['varA','varB']
d['varVal']=[[10],[1,0]]

df = {k:v for k,v in d.items() if v is not None}
keys, values = zip(*df.items())
res = [dict(zip(keys, v)) for v in it.product(*values)]

期望的结果

在字典之间添加额外空间以帮助进行视觉呈现。

res = [
    {'n1': 1,
     'varName': ['varA', 'varB'],
     'varString': 'ExampleText',
     'varVal': [[10], [0]]},

    {'n1': 100,
     'varName': ['varA', 'varB'],
     'varString': 'ExampleText',
     'varVal': [[10], [0]]},

    {'n1': 1,
     'varName': ['varA', 'varB'],
     'varString': 'ExampleText',
     'varVal': [[10], [1]]},

    {'n1': 100,
     'varName': ['varA', 'varB'],
     'varString': 'ExampleText',
     'varVal': [[10], [1]]}
]

1 个答案:

答案 0 :(得分:0)

彼得的评论让我思考这个问题有点不同导致了这个答案。

此答案分别处理导致问题的条目,然后进行一些后处理以返回所需的格式。基本上创建和附加步骤,掩盖导致问题的最终所需字典格式。

如果有一种方法可以用原始问题中指定的更直接的方法处理,我很想知道。感谢那些评论的人。

<强>解决方案

import itertools as it

def standKeys():
    # Standard input parameters for dymola.simulateExtendedModel
    keys = ['n1',
            'n2',
            'varString',
            'varName',
            'varVal']
    return keys


def initSettings():
    # Initialize the settings parameters
    simSettings = {}
    for key in standKeys():
            simSettings[key]=None

    return simSettings

def genExperimentsRaw(simSettings):
    # Remove None and generate all experiment permutations
    simSettingsfiltered = {k:v for k,v in simSettings.items() if v is not None}
    keys, values = zip(*simSettingsfiltered.items())
    experimentsRaw = [dict(zip(keys, v)) for v in it.product(*values)]

    return experimentsRaw

def genExperiments(experimentsRaw):
    # Filter experiments to generate key/value pairs for 'varName' and 'varVal'
    allKeys = standKeys()
    experiments = []
    for i, value in enumerate(experimentsRaw):
        initialNames = []
        initialValues = []
        for key, val in value.items(): 
            if key not in allKeys:
                initialNames.append(key)
                initialValues.append(val)
                value.pop(key)
        value['varName']=initialNames
        value['varVal']=initialValues

        experiments.append(initSettings())
        experiments[i].update(value)

    return experiments

if __name__ == "__main__":
    d={}
    d['n1']=[1,100]
    d['n2']=None
    d['varString']=['ExampleText']
    # Original
    # d['varName']=['varA','varB'] # Remove this
    # d['varVal']=[[10],[1,0]]

    # Separate out and treat like other dictionary keys
    d['varA']=[10]
    d['varB']=[1,0]

# Generate all experiment permutations
experimentsRaw = genExperimentsRaw(d)

# Filter experiments to generate key/value pairs for 'varName' and 'varVal'
experiments = genExperiments(experimentsRaw)

<强>结果

[{'n1': 1,
  'n2': None,
  'varName': ['varA', 'varB'],
  'varString': 'ExampleText',
  'varVal': [10, 1]},
 {'n1': 1,
  'n2': None,
  'varName': ['varA', 'varB'],
  'varString': 'ExampleText',
  'varVal': [10, 0]},
 {'n1': 100,
  'n2': None,
  'varName': ['varA', 'varB'],
  'varString': 'ExampleText',
  'varVal': [10, 1]},
 {'n1': 100,
  'n2': None,
  'varName': ['varA', 'varB'],
  'varString': 'ExampleText',
  'varVal': [10, 0]}]