首页 > 解决方案 > 当单个键有多个值时拆分 Python 字典

问题描述

我有 Python 字典,有时对于单个键,多个值由逗号分隔(例如“value1,value2”)表示。在这些情况下,我需要将字典分成许多多个值(请参阅问题底部,例如所需的输出)。字典中每个键只能有一个值,否则它需要是一个完全独立的字典。

我试图遍历字典并在找到具有多个值的值时使用 popitem 函数。然后创建单独的字典并附加它们。但是我遇到了运行时错误。而且我怀疑可能有更优雅的解决方案。

例如

x = {"name":"alice", "age":20,"hobby":"badminton, basketball", "language":"python"}
for eachkey, value in x.items():
    if ", " in value:
        x.popitem()

在进一步了解之前获得以下错误:

RuntimeError: dictionary changed size during iteration

这是预期输入和输出的示例:

输入

x = {"name":"alice", "age":20,"hobby":"badminton, basketball", "language":"python"}

输出

[
    {"name":"alice", "age":20,"hobby":"badminton", "language":"python"},
    {"name":"alice", "age":20,"hobby":"basketball", "language":"python"}
]

或另一个具有多个键和多个值的示例:(
在@isaactfa 回答后为澄清而编辑+包含在内)

输入

x = {"name":"alice", "age":20,"hobby":"badminton, basketball", "language":"python, go"}

输出

[
    {'name': 'alice', 'age': 20, 'hobby': 'badminton', 'language': 'python'}, 
    {'name': 'alice', 'age': 20, 'hobby': 'badminton', 'language': 'go'}, 
    {'name': 'alice', 'age': 20, 'hobby': 'basketball', 'language': 'python'}, 
    {'name': 'alice', 'age': 20, 'hobby': 'basketball', 'language': 'go'}
]

标签: python

解决方案


我首先将输入转换为键值元组列表(哦,好吧)

def unwrap(d):
    for k, v in d.items():
        if isinstance(v, str):
            yield [(k, v2.strip()) for v2 in v.split(',')]
        else:
            yield [(k, v)]

这样与

d = {
    "name": "alice",
    "age": 20,
    "hobby": "badminton, basketball",
    "language": "python, go"
}

它会回来

[
    [('name', 'alice')], 
    [('age', 20)], 
    [('hobby', 'badminton'), ('hobby', 'basketball')], 
    [('language', 'python'), ('language', 'go')]
]

完成后,申请itertools.product将其转换为所有可能的字典列表:

result = [
    dict(x)
    for x in product(*unwrap(d))
]

result存在

[
    {'name': 'alice', 'age': 20, 'hobby': 'badminton', 'language': 'python'}, 
    {'name': 'alice', 'age': 20, 'hobby': 'badminton', 'language': 'go'}, 
    {'name': 'alice', 'age': 20, 'hobby': 'basketball', 'language': 'python'}, 
    {'name': 'alice', 'age': 20, 'hobby': 'basketball', 'language': 'go'}
]

推荐阅读