如何遍历字典的所有可能值?

时间:2019-07-02 22:19:24

标签: python dictionary

我有一个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
}

那么第三个是这个... (请注意,key1如何返回到1)

{
    "key0": {
        "key1": 1,
        "key2": 9
    }
    "key3": 22
}

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

4 个答案:

答案 0 :(得分:2)

这里是一种使用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}]

答案 1 :(得分:0)

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

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])

这应该有效

答案 2 :(得分:0)

这是我的解决方法:

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

def iterate (key, index):
    if (type(key) == list):
        if (index >= len(key)):
            return (key[0])
        else:
            return (key[index])
    elif (type(key) == dict):
        result = {}
        for item in key:
            result[item] = iterate(key[item], index)
        return result

执行以下测试后,我得到了您谈论的结果

>>> iterate(xdict, 0)
{'key0': {'key1': 1, 'key2': 8}, 'key3': 22}
>>> iterate(xdict, 1)
{'key0': {'key1': 2, 'key2': 9}, 'key3': 23}
>>> iterate(xdict, 2)
{'key0': {'key1': 1, 'key2': 10}, 'key3': 24}

答案 3 :(得分:0)

这是我的尝试(对不起,订单不正确):

from collections import OrderedDict
from itertools import product
from copy import deepcopy


input_dicts = {'key0': {'key1': [1, 2], 'key2': [8, 9, 10]}, 'key3': [22, 23, 24]}
input_list_of_list = []
od = OrderedDict()

for k, v in input_dicts.items():
    if isinstance(v, list):
        input_list_of_list.append(v)
        od[k] = None
    elif isinstance(v, dict):
        od[k] = OrderedDict()
        for k1, v1 in v.items():
            if isinstance(v1, list):
                input_list_of_list.append(v1)
                od[k][k1] = None

all_combinations = product(*input_list_of_list)
output = []
for c in all_combinations:
    l = len(c)
    s = 0
    for k, v in od.items():
        if not isinstance(v, dict):
            od[k] = c[s]
            s += 1
        else:
            for k1 in v:
                od[k][k1] = c[s]
                s += 1
    output.append(deepcopy(od))

输出:

[
    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)]),
]