Warning: file_get_contents(/data/phpspider/zhask/data//catemap/1/list/4.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/jsf-2/2.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Python 从列表字典创建n个嵌套循环_Python_List_Dictionary_Multidimensional Array_Iterator - Fatal编程技术网

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

Python 从列表字典创建n个嵌套循环,python,list,dictionary,multidimensional-array,iterator,Python,List,Dictionary,Multidimensional Array,Iterator,我有一本有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['

我有一本有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
...
您应该使用,它执行,这是您尝试执行的操作的名称

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
请注意,字典中没有硬编码键数的地方。如果您使用一个而不是
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

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

您可以使用递归函数:

# make a list of all the keys
keys = list(dict.keys())

def f(keys, dict, depth=0, to_print=[]):
    if depth < len(keys):
        for item in dict[keys[depth]]:
            to_print.append(keys[depth] + '.' + item + ' ')
            f(keys, dict, depth + 1, to_print)
            del to_print[-1]
    else:
        # you can format the output as you wish; here i'm just printing the list
        print to_print


# call the function
f(keys, dict)
#列出所有键
键=列表(dict.keys())
def(键,dict,深度=0,to_print=[]):
如果深度
我想要一种更实用的风格,它与@Senshin的答案基本相同:

import itertools
from pprint import pprint
def foo(d):
    def g(item):
        """create and return key.value1, key.value2, ..., key.valueN iterator

        item is a (key, value) dictionary item, assumes value is a sequence/iterator
        """
        # associate the key with each value - (key, value0) ... (key, valueN)
        kay_vees = itertools.izip(itertools.repeat(item[0]), item[1])
        return itertools.imap('.'.join, kay_vees)

    # generator that produces n data sets from the dict
    a = itertools.imap(g, d.iteritems())

    # cartesian product of the datasets
    return itertools.product(*a)
用法:

c = list(foo(d))
pprint(c)

for thing in foo(d):
    print thing

一旦被使用,迭代器需要重新定义-
foo
将为每个调用返回一个新的迭代器。

您能包含预期的输出吗?他/她希望将其概括为n键谢谢,这解决了问题,但我不只是想打印一个长列表,我想用变量做其他的事情,所以把迭代器隐藏在函数中会使它成为一个可移植性较差的解决方案。您仍然可以对else子句中的变量执行其他操作。我喜欢此解决方案,但是否有任何方法可以使其更加优雅,因为当前键必须在
results=product(*values)
和for循环之间保持相同的顺序。除了
zip(键,结果)
@alexmcf查看我的编辑(在下面一行),是否还有其他链接
结果
。是-您可以将产品置于(键、值)元组列表之上,而不是值列表之上。这可能比我最初发布的方式要好。只是给将来使用此功能的人一个提示。。。如果列表中有任何空列表,则该操作将失败dict@alexmcf确实,如果dict中有空列表,您将不会得到任何输出。您希望得到什么输出?这是一个相当具体的问题,我使用空列表表示我需要调用API,用每个可能的值填充它们,而不是硬编码预定义值。代码工作得很好,我现在知道如何在物理考试之外应用笛卡尔积了