Python 如何迭代字典中所有可能的值?

Python 如何迭代字典中所有可能的值?,python,dictionary,Python,Dictionary,我有一个python字典,其中每个条目的值要么是一个列表,要么是另一个条目也是列表的字典。我想创建一个python迭代器,它迭代字典的所有可能状态,其中每个键处的列表定义该键的可能值 我尝试遍历每个键,并在列表中找到下一个元素用作值,但这只涵盖了一些组合。这是因为一旦列表用尽,您需要重置为第一个值并移动到下一个列表 如果我们把这个命令给迭代器 { "key0": { "key1": [1, 2], "key2": [8, 9, 10] }

我有一个python字典,其中每个条目的值要么是一个列表,要么是另一个条目也是列表的字典。我想创建一个python迭代器,它迭代字典的所有可能状态,其中每个键处的列表定义该键的可能值

我尝试遍历每个键,并在列表中找到下一个元素用作值,但这只涵盖了一些组合。这是因为一旦列表用尽,您需要重置为第一个值并移动到下一个列表

如果我们把这个命令给迭代器

{
    "key0": {
        "key1": [1, 2],
        "key2": [8, 9, 10]
    }
    "key3": [22, 23, 24]
}
它应该产生的第一个迭代是

{
    "key0": {
        "key1": 1,
        "key2": 8
    }
    "key3": 22
}
{
    "key0": {
        "key1": 2,
        "key2": 8
    }
    "key3": 22
}
第二个是这个

{
    "key0": {
        "key1": 1,
        "key2": 8
    }
    "key3": 22
}
{
    "key0": {
        "key1": 2,
        "key2": 8
    }
    "key3": 22
}
第三个是这个。。。 (注意key1如何返回到1)


预期结果是迭代字典的每个可能状态(总共18个),其中每个键处的列表定义该键的可能值。

字典不是有序结构,您不应该尝试迭代它们。但是,如果必须这样做,可以采用以下方法:

my_dict = {"a":1 ,"b":2,"c":3}

for key in my_dict.keys():
    #print the key
    print(key)
    #print the value corresponding to the key
    print(my_dict[key])
用你想要的任何功能替换指纹,你会没事的!如果您有嵌套的字典或列表,请记住这些值(在您的情况下)就是字典或列表,从那里,您可以以类似的方式在循环中操纵它们

my_dict = {"a":{"a_1":1,"a_2":2} ,"b":{"b_1":1,"b_2":2},"c":{"b_1":1,"b_2":2}}

for key in my_dict.keys():
    #print the key
    print(key)
    #print the dictionary corresponding to the key
    print(my_dict[key])
    for new_key in my_dict[key].keys():
        #print the keys of the nested dictionaries
        print(new_key)
        #print the values of the nested dictionaries
        print(my_dict[key][new_key])

这应该行得通

以下是我的解决方案:

xdict={
“密钥0”:{
“键1”:[1,2],
“键2”:[8,9,10]
},
“键3”:[22,23,24]
}
def迭代(键,索引):
如果(类型(键)=列表):
如果(索引>=len(键)):
返回(键[0])
其他:
返回(键[索引])
elif(类型(键)=dict):
结果={}
对于键中的项目:
结果[项目]=迭代(键[项目],索引)
返回结果
在执行了以下测试之后,我得到了您提到的结果

迭代(xdict,0) {'key0':{'key1':1,'key2':8},'key3':22} >>>迭代(xdict,1) {'key0':{'key1':2'key2':9},'key3':23} >>>迭代(xdict,2) {'key0':{'key1':1,'key2':10},'key3':24} 这是我的尝试(抱歉,订单还不正确):

输出:

[
    OrderedDict([("key0", OrderedDict([("key1", 1), ("key2", 8)])), ("key3", 22)]),
    OrderedDict([("key0", OrderedDict([("key1", 1), ("key2", 8)])), ("key3", 23)]),
    OrderedDict([("key0", OrderedDict([("key1", 1), ("key2", 8)])), ("key3", 24)]),
    OrderedDict([("key0", OrderedDict([("key1", 1), ("key2", 9)])), ("key3", 22)]),
    OrderedDict([("key0", OrderedDict([("key1", 1), ("key2", 9)])), ("key3", 23)]),
    OrderedDict([("key0", OrderedDict([("key1", 1), ("key2", 9)])), ("key3", 24)]),
    OrderedDict([("key0", OrderedDict([("key1", 1), ("key2", 10)])), ("key3", 22)]),
    OrderedDict([("key0", OrderedDict([("key1", 1), ("key2", 10)])), ("key3", 23)]),
    OrderedDict([("key0", OrderedDict([("key1", 1), ("key2", 10)])), ("key3", 24)]),
    OrderedDict([("key0", OrderedDict([("key1", 2), ("key2", 8)])), ("key3", 22)]),
    OrderedDict([("key0", OrderedDict([("key1", 2), ("key2", 8)])), ("key3", 23)]),
    OrderedDict([("key0", OrderedDict([("key1", 2), ("key2", 8)])), ("key3", 24)]),
    OrderedDict([("key0", OrderedDict([("key1", 2), ("key2", 9)])), ("key3", 22)]),
    OrderedDict([("key0", OrderedDict([("key1", 2), ("key2", 9)])), ("key3", 23)]),
    OrderedDict([("key0", OrderedDict([("key1", 2), ("key2", 9)])), ("key3", 24)]),
    OrderedDict([("key0", OrderedDict([("key1", 2), ("key2", 10)])), ("key3", 22)]),
    OrderedDict([("key0", OrderedDict([("key1", 2), ("key2", 10)])), ("key3", 23)]),
    OrderedDict([("key0", OrderedDict([("key1", 2), ("key2", 10)])), ("key3", 24)]),
]

下面是一个使用
itertools.product
和递归的简明方法:

from itertools import product

def traverse(d):
    K,V = zip(*d.items())
    for v in product(*(v if isinstance(v,list) else traverse(v) for v in V)):
        yield dict(zip(K,v))
样本运行:

>>> d = {
>>>     "key0": {
>>>         "key1": [1, 2],
>>>         "key2": [8, 9, 10]
>>>     },
>>>     "key3": [22, 23, 24]
>>> }

>>> from pprint import pprint
>>> pprint([*traverse(d)])
[{'key0': {'key1': 1, 'key2': 8}, 'key3': 22},
 {'key0': {'key1': 1, 'key2': 8}, 'key3': 23},
 {'key0': {'key1': 1, 'key2': 8}, 'key3': 24},
 {'key0': {'key1': 1, 'key2': 9}, 'key3': 22},
 {'key0': {'key1': 1, 'key2': 9}, 'key3': 23},
 {'key0': {'key1': 1, 'key2': 9}, 'key3': 24},
 {'key0': {'key1': 1, 'key2': 10}, 'key3': 22},
 {'key0': {'key1': 1, 'key2': 10}, 'key3': 23},
 {'key0': {'key1': 1, 'key2': 10}, 'key3': 24},
 {'key0': {'key1': 2, 'key2': 8}, 'key3': 22},
 {'key0': {'key1': 2, 'key2': 8}, 'key3': 23},
 {'key0': {'key1': 2, 'key2': 8}, 'key3': 24},
 {'key0': {'key1': 2, 'key2': 9}, 'key3': 22},
 {'key0': {'key1': 2, 'key2': 9}, 'key3': 23},
 {'key0': {'key1': 2, 'key2': 9}, 'key3': 24},
 {'key0': {'key1': 2, 'key2': 10}, 'key3': 22},
 {'key0': {'key1': 2, 'key2': 10}, 'key3': 23},
 {'key0': {'key1': 2, 'key2': 10}, 'key3': 24}]

当然有
OrderedDict
,但从python 3.6开始,字典保持插入顺序。感谢您的输入,了解它很有用!这不能回答我的问题,有几个原因。因为你给了我一个函数而不是迭代器。2因为它没有告诉我如何跟踪我增加的值。它只适用于双嵌套dict。我明白你的意思,但这个解决方案只产生18种可能组合中的3种。我想要所有的答案。现在,如果有一些dict条目是INT而不是列表,并且在所有迭代过程中保持不变,该怎么办?如果我在product(*(v if isinstance(v,list)else遍历(v)if isinstance(v,dict)else[v]for v in v))中尝试使用
,我会得到一个错误:
尝试用它代替当前的
for
语句,@ColmanKoivisto