从列表字典创建n个嵌套循环 - python

我有一本有n个键的字典,每个键都包含n个字符串的列表。

我想遍历字符串的每个组合,产生键和与其关联的字符串。

这是一个具有3个键的字典的示例,但我想归纳为具有n个键的字典。

dict = {'key1':['str0','str1','str2','strn'],'key2':['apples','bananas','mangos'],'key3':['spam','eggs','more spam']}

for str1 in dict['key1']:
    for str2 in dict['key2']:
        for str3 in dict['key3']:
            print 'key1'+"."+str1,'key2'+"."+str2,'key3'+"."+str3

请回答问题时,您能否描述答案的工作方式,因为我是python的新手,还不知道所有可用的工具!

预期产量:

key1.str0 key2.apples key3.spam
key1.str0 key2.apples key3.eggs
key1.str0 key2.apples key3.more spam
key1.str0 key2.bananas key3.spam
key1.str0 key2.bananas key3.eggs
...

n维迭代器的预期输出:

key1.str0 key2.apples key3.spam ... keyn.string0
key1.str0 key2.apples key3.spam ... keyn.string1
key1.str0 key2.apples key3.spam ... keyn.string2
...
key1.str0 key2.apples key3.spam ... keyn.stringn
...

python大神给出的解决方案

您应该使用itertools.product,它执行Cartesian product,这是您要尝试执行的操作的名称。

from itertools import product

# don't shadow the built-in name `dict`
d = {'key1': ['str0','str1','str2','strn'], 'key2': ['apples','bananas','mangos'], 'key3': ['spam','eggs','more spam']}

# dicts aren't sorted, but you seem to want key1 -> key2 -> key3 order, so 
# let's get a sorted copy of the keys
keys = sorted(d.keys())
# and then get the values in the same order
values = [d[key] for key in keys]

# perform the Cartesian product
# product(*values) means product(values[0], values[1], values[2], ...)
results = product(*values)

# each `result` is something like ('str0', 'apples', 'spam')
for result in results:
    # pair up each entry in `result` with its corresponding key
    # So, zip(('key1', 'key2', 'key3'), ('str0', 'apples', 'spam'))
    # yields (('key1', 'str0'), ('key2', 'apples'), ('key3', 'spam'))
    # schematically speaking, anyway
    for key, thing in zip(keys, result):
        print key + '.' + thing, 
    print

请注意,我们在哪里都没有对字典中的键数进行硬编码。如果使用collections.OrderedDict而不是dict,则可以避免排序。

如果要将键附加到它们的值,这是另一个选择:

from itertools import product

d = {'key1': ['str0','str1','str2','strn'], 'key2': ['apples','bananas','mangos'], 'key3': ['spam','eggs','more spam']}

foo = [[(key, value) for value in d[key]] for key in sorted(d.keys())]

results = product(*foo)
for result in results:
    for key, value in result:
        print key + '.' + value,
    print

在这里,我们构造(键,值)元组的列表列表,然后将笛卡尔乘积应用于列表。这样,键和值之间的关系完全包含在results中。想一想,这可能比我发布的第一种方法更好。