用pythonic方法来破坏一个dict,它的值是多个dict的列表

2024-10-03 23:17:42 发布

您现在位置:Python中文网/ 问答频道 /正文

说明

  • 我需要把一个dict,它的值是一个列表,分解成几个dict,保留其他部分
  • 我想要断开的键可能有不同的名称,但是cond只会得到一个类型为list的值

示例

  • 输入
cond = {"type":"image","questionType":["3","4","5"]}

cond = {"type":"example","fieldToBreak":["1","2","3"],"fieldInt":1,"fieldFloat":0.1}
  • 输出
[
    {'type': 'image', 'questionType': '3'}, 
    {'type': 'image', 'questionType': '4'}, 
    {'type': 'image', 'questionType': '5'}
]

[
    {'type': 'example', 'fieldToBreak': '1', 'fieldInt': 1, 'fieldFloat': 0.1},
    {'type': 'example', 'fieldToBreak': '2', 'fieldInt': 1, 'fieldFloat': 0.1},
    {'type': 'example', 'fieldToBreak': '3', 'fieldInt': 1, 'fieldFloat': 0.1}
]

我所尝试的

cond_queue = []
for k,v in cond.items():
    if isinstance(v,list):
        for ele in v:
            cond_copy = cond.copy()
            cond_copy[k] = ele
            cond_queue.append(cond_copy)
        break
  • 它是有效的,但我认为它不是最好的pythonic解决方案

问题:

  • 有更好的肾盂疗法吗

Tags: inimageforqueueexampletypedictlist
3条回答

利用python内置函数和标准库的可能方法。该代码可以与任意数量的键一起使用。在原始目录中出现多个列表的情况下,它会创建值元素的所有组合。不确定此逻辑是否正确

import itertools

def dict_to_inflated_list(d):

    ans, keys, vals = list(), list(), list()

    # copy keys and 'listified' values in the same order
    for k, v in d.items():
        keys.append(k)
        vals.append(v if isinstance(v, list) else [v])

    # iterate over all possible combinations of elements of all 'listified' values
    for combination in itertools.product(*vals):
        ans.append({k: v for k, v in zip(keys, combination)})

    return ans

if __name__ == '__main__':

    cond = {'type': 'image', 'questionType': ['3', '4', '5']}
    print(dict_to_inflated_list(cond))

    cond = {'a': 0, 'b': [1, 2], 'c': [10, 20]}
    print(dict_to_inflated_list(cond))

输出:

[{'type': 'image', 'questionType': '3'}, {'type': 'image', 'questionType': '4'}, {'type': 'image', 'questionType': '5'}]
[{'a': 0, 'b': 1, 'c': 10}, {'a': 0, 'b': 1, 'c': 20}, {'a': 0, 'b': 2, 'c': 10}, {'a': 0, 'b': 2, 'c': 20}]

除了输入字典之外,这个小函数不需要任何额外的参数就可以完成这项工作

def unpack_dict(d):
    n = [len(v) for k,v in d.items() if type(v) is list][0] #number of items in the list
    r = []
    for i in range(n):
        _d = {}
        for k,v in d.items():
            if type(v) is list:
                _d[k] = v[i]
            else:
                _d[k] = v
        r.append(_d)
    return r
    
    


cond = {"type":"example","fieldToBreak":["1","2","3"],"fieldInt":1,"fieldFloat":0.1}

unpack_dict(cond)

[{'type': 'example', 'fieldToBreak': '1', 'fieldInt': 1, 'fieldFloat': 0.1},
 {'type': 'example', 'fieldToBreak': '2', 'fieldInt': 1, 'fieldFloat': 0.1},
 {'type': 'example', 'fieldToBreak': '3', 'fieldInt': 1, 'fieldFloat': 0.1}]

函数确定列表项中有多少项(n),并使用该信息提取要插入字典的正确值。在nfor i in range(n):)上循环用于在最终输出中追加正确数量的词典。就这样。很容易阅读和理解

类似于下面的内容(解决方案基于帖子的输入,我假设它代表了一般情况)

cond = {"type": "image", "questionType": ["3", "4", "5"]}
data = [{"type": "image", "questionType": e} for e in cond['questionType']]
print(data)

输出

[{'type': 'image', 'questionType': '3'}, {'type': 'image', 'questionType': '4'}, {'type': 'image', 'questionType': '5'}]

相关问题 更多 >