【问题标题】:Python3 itertools.permutations on dict of lists?Python3 itertools.permutations 对列表的字典?
【发布时间】:2019-09-14 08:41:39
【问题描述】:

假设我有一个列表字典。每个键代表一个变量,每个列表代表变量可以具有的可能值。

myBools = [ True, False ]
myInts = [ -3, 0, 4 ]
myFloats = [ -2.2, 0.0, 1.1 ]

myDict = {
    'aBool': myBools,
    'bInt': myInts,
    'cFloat': myFloats,
}

现在,我如何获取 aBool、bInt 和 cFloat 的所有排列的字典列表?每个列表条目将是一个字典。每个 dict 都有一组唯一的值,代表一个排列。

预期:

myPermList = [
    { 'aBool': True, 'bInt': -3, 'cFloat': -2.2 },
    { 'aBool': True, 'bInt': -3, 'cFloat': 0.0 },
    { 'aBool': True, 'bInt': -3, 'cFloat': 1.1 },
    # ...
    { 'aBool': False, 'bInt': 4, 'cFloat': -2.2 },
    { 'aBool': False, 'bInt': 4, 'cFloat': 0.0 },
    { 'aBool': False, 'bInt': 4, 'cFloat': 1.1 },
]

我无法确定 itertools.permutations 是否可以帮助我,如果可以,如何设置通话。

这种技术的预期用途是帮助以全面和系统的方式自动测试其他一些功能,以便我可以扩展列表以包含好数据和坏数据,以便在数据好的情况下测试正确的功能并在数据错误的情况下进行适当的错误处理。

myBools、myInts 和 myFloats 将代表可以重用的各种数据类型的测试。这些将来可能会混合使用(即测试 int 和 float 数据)。但所写的代码代表了我能想到的最简单、最通用的输入和输出数据结构。

编辑注释1:

我发现我最初安排问题的方式存在限制,无法实现我想要的自动化水平。可重用集的初始定义将集名称保留为变量。但是,这可能是未来相关的元数据,如果存储为字典键而不是尝试使用代码分析或元编程技术进行提取,将更容易访问。

随后,我为 myDict 选择一个更具描述性的名称,例如我的选项。然后,我用额外的集合和选项更明确地展示了意图。现在,如果我想用额外的代码分析选项,那就容易多了。这并没有真正改变最初的问题,只是包括更多的操作来设置将要使用的 itertools 函数(乘积或排列)。

最后,由于我显然不是在寻找排列,而是在寻找笛卡尔积(感谢您的更正!),我将存储结果是一个更准确、更简单的名称 myOptsList。

mySets = {
    'myBools1': [ True, False ],
    'myInts1': [ -3, 0, 4 ],
    'myFloats1': [ -2.2, 0.0, 1.1 ],
    'myInts2': [ -500, -250, 0, 250, 500 ],
    'myFloats2': [ -88.8, -44.4, -0.0, +0.0, 44.4, 88.8 ],
    # ... arbitrary number of sets
}

myOptions = {
    'aBool': mySets[ 'myBools1' ],
    'bInt': mySets[ 'myInts1' ],
    'cFloat': mySets[ 'myFloats1' ],
    'dInt': mySets[ 'myInts1' ],
    'eInt': mySets[ 'myInts2' ],
    'fInt': mySets[ 'myInts1' ],
    'gFloat': mySets[ 'myFloats2' ],
    # ... arbitary number of options,
    #     potentially reusing sets
}

# Set up parameters and find Cartesian product

myOptsList = [
    { 'aBool': True, 'bInt': -3, 'cFloat': -2.2, 'dInt': -3, 'eInt': -500, 'fInt': -3, 'gFloat': -88.8 },
    # ...
    { 'aBool': False, 'bInt': 4, 'cFloat': 1.1, 'dInt': 4, 'eInt': 500, 'fInt': 4, 'gFloat': 88.8 },
]

【问题讨论】:

  • 您只想要可用的选项?不要在mySets 中使用lists,而是使用set。当您更新问题时,我们不会收到更新。您的更新更具体,但并未引起对您的问题的新关注。

标签: python-3.x list dictionary iterator permutation


【解决方案1】:

如果您不先将其放入dict 会更快,但此解决方案有效。这也是动态的,如果您向 dict 添加条目和列表,则解决方案仍将按预期工作。

from itertools import product # This will get all permutations

myBools = [ True, False ]
myInts = [ -3, 0, 4 ]
myFloats = [ -2.2, 0.0, 1.1 ]

myDict = {
    'aBool': myBools,
    'bInt': myInts,
    'cFloat': myFloats,
} 

# First we need to grab the keys and values
keys, vals = list(myDict.keys()), list(myDict.values())

# Then we find all permutations for those values
permutations = list(product(*vals))

# Finally we can create out list of dicts
result = [{keys[index]: entry[index] for index in range(len(entry))} for entry in permutations]
# You combine the above to statements into a single list comprehension 
# if you want but I though this way was more readable.

for x in result:
    print(x)

输出:

{'aBool': True, 'bInt': -3, 'cFloat': -2.2}
{'aBool': True, 'bInt': -3, 'cFloat': 0.0}
{'aBool': True, 'bInt': -3, 'cFloat': 1.1}
{'aBool': True, 'bInt': 0, 'cFloat': -2.2}
{'aBool': True, 'bInt': 0, 'cFloat': 0.0}
{'aBool': True, 'bInt': 0, 'cFloat': 1.1}
{'aBool': True, 'bInt': 4, 'cFloat': -2.2}
{'aBool': True, 'bInt': 4, 'cFloat': 0.0}
{'aBool': True, 'bInt': 4, 'cFloat': 1.1}
{'aBool': False, 'bInt': -3, 'cFloat': -2.2}
{'aBool': False, 'bInt': -3, 'cFloat': 0.0}
{'aBool': False, 'bInt': -3, 'cFloat': 1.1}
{'aBool': False, 'bInt': 0, 'cFloat': -2.2}
{'aBool': False, 'bInt': 0, 'cFloat': 0.0}
{'aBool': False, 'bInt': 0, 'cFloat': 1.1}
{'aBool': False, 'bInt': 4, 'cFloat': -2.2}
{'aBool': False, 'bInt': 4, 'cFloat': 0.0}
{'aBool': False, 'bInt': 4, 'cFloat': 1.1}

【讨论】:

  • 请提供更多详细信息,说明您在问题中实际尝试执行的操作(或您想要实际实现的操作)。 包括一个例子。我不太明白你想做什么。
【解决方案2】:

事实上,你不想要排列。你想要笛卡尔积。

from itertools import product
myPermList = [{'aBool':c[0],'bInt':c[1],'cFloat':c[2]} for c in list(product(myBools,myInts,myFloats))]

输出:

[{'aBool': True, 'bInt': -3, 'cFloat': -2.2},
 {'aBool': True, 'bInt': -3, 'cFloat': 0.0},
 {'aBool': True, 'bInt': -3, 'cFloat': 1.1},
 {'aBool': True, 'bInt': 0, 'cFloat': -2.2},
 {'aBool': True, 'bInt': 0, 'cFloat': 0.0},
 {'aBool': True, 'bInt': 0, 'cFloat': 1.1},
 {'aBool': True, 'bInt': 4, 'cFloat': -2.2},
 {'aBool': True, 'bInt': 4, 'cFloat': 0.0},
 {'aBool': True, 'bInt': 4, 'cFloat': 1.1},
 {'aBool': False, 'bInt': -3, 'cFloat': -2.2},
 {'aBool': False, 'bInt': -3, 'cFloat': 0.0},
 {'aBool': False, 'bInt': -3, 'cFloat': 1.1},
 {'aBool': False, 'bInt': 0, 'cFloat': -2.2},
 {'aBool': False, 'bInt': 0, 'cFloat': 0.0},
 {'aBool': False, 'bInt': 0, 'cFloat': 1.1},
 {'aBool': False, 'bInt': 4, 'cFloat': -2.2},
 {'aBool': False, 'bInt': 4, 'cFloat': 0.0},
 {'aBool': False, 'bInt': 4, 'cFloat': 1.1}]

【讨论】:

  • 嵌套问题使对原始问题及其后续发展的理解变得复杂。然后,我的建议是提出一个新问题。如果我了解您更新的问题,应该很容易解决它。 ;)
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-10-03
  • 2018-08-02
  • 1970-01-01
  • 1970-01-01
  • 2020-10-31
相关资源
最近更新 更多