使用Python从字典的列表值中获取组合

24 投票
4 回答
7066 浏览
提问于 2025-04-16 05:05

我有一个这样的输入值:

variants = {
  "debug" : ["on", "off"],
  "locale" : ["de_DE", "en_US", "fr_FR"],
  ...
}

我想处理这些值,得到以下结果:

combinations = [
  [{"debug":"on"},{"locale":"de_DE"}],
  [{"debug":"on"},{"locale":"en_US"}],
  [{"debug":"on"},{"locale":"fr_FR"}],
  [{"debug":"off"},{"locale":"de_DE"}],
  [{"debug":"off"},{"locale":"en_US"}],
  [{"debug":"off"},{"locale":"fr_FR"}]
]

这个方法应该可以处理字典中任意长度的键。我尝试过在Python中使用itertools,但没有找到符合这些要求的东西。

4 个回答

3

这是我使用的:

from itertools import product

def dictproduct(dct):
    for t in product(*dct.itervalues()):
        yield dict(zip(dct.iterkeys(), t))

在你的例子中应用后,得到:

>>> list(dictproduct({"debug":["on", "off"], "locale":["de_DE", "en_US", "fr_FR"]}))
[{'debug': 'on', 'locale': 'de_DE'},
 {'debug': 'on', 'locale': 'en_US'},
 {'debug': 'on', 'locale': 'fr_FR'},
 {'debug': 'off', 'locale': 'de_DE'},
 {'debug': 'off', 'locale': 'en_US'},
 {'debug': 'off', 'locale': 'fr_FR'}]

我觉得这样比上面的单行代码更容易读懂。

另外,它返回的是一个迭代器,类似于 itertools.product,这就让用户可以选择是创建一个列表,还是一次只处理一个值。

7

当然可以!请看下面的内容:

在编程中,有时候我们需要让程序在特定的条件下执行某些操作。这就像给程序设定了一些规则,只有当这些规则被满足时,程序才会做出反应。

比如说,你可能希望当用户点击一个按钮时,程序才会显示一条消息。这个过程就叫做“事件处理”。事件处理就是让程序能够对用户的操作做出反应。

在很多编程语言中,我们会使用“函数”来处理这些事件。函数就像一个小工具,当你需要的时候就可以把它拿出来用。你只需要告诉程序在什么情况下要使用这个工具,以及这个工具应该做些什么。

总之,事件处理和函数的结合让我们的程序变得更加智能,能够根据用户的行为来做出相应的反应。

combinations = [[{key: value} for (key, value) in zip(variants, values)] 
                for values in itertools.product(*variants.values())]

[[{'debug': 'on'}, {'locale': 'de_DE'}],
 [{'debug': 'on'}, {'locale': 'en_US'}],
 [{'debug': 'on'}, {'locale': 'fr_FR'}],
 [{'debug': 'off'}, {'locale': 'de_DE'}],
 [{'debug': 'off'}, {'locale': 'en_US'}],
 [{'debug': 'off'}, {'locale': 'fr_FR'}]]
34
import itertools as it

varNames = sorted(variants)
combinations = [dict(zip(varNames, prod)) for prod in it.product(*(variants[varName] for varName in varNames))]

嗯,这个返回的是:

[{'debug': 'on', 'locale': 'de_DE'},
 {'debug': 'on', 'locale': 'en_US'},
 {'debug': 'on', 'locale': 'fr_FR'},
 {'debug': 'off', 'locale': 'de_DE'},
 {'debug': 'off', 'locale': 'en_US'},
 {'debug': 'off', 'locale': 'fr_FR'}]

这可能不是你想要的结果。让我来调整一下...

combinations = [ [ {varName: val} for varName, val in zip(varNames, prod) ] for prod in it.product(*(variants[varName] for varName in varNames))]

现在返回的是:

[[{'debug': 'on'}, {'locale': 'de_DE'}],
 [{'debug': 'on'}, {'locale': 'en_US'}],
 [{'debug': 'on'}, {'locale': 'fr_FR'}],
 [{'debug': 'off'}, {'locale': 'de_DE'}],
 [{'debug': 'off'}, {'locale': 'en_US'}],
 [{'debug': 'off'}, {'locale': 'fr_FR'}]]

瞧!;-)

撰写回答