如何用Python将一个字典根据 key 值拆分成多个字典?

现在有一个字典 a: a = { '0106': '50', '0117': '35', '0203': '30', '0205': '30', '3302': '45', '3305': '45' } 如何根据 key 值前面的两位数拆分成字典 b: b = { '01': { '0106': '50', '0117': '35', }, '02': { '0203': '30', '0205': '30', }, '33': { '3302': '45', '3305': '45', } }

请问大神用 python 代码如何优雅的实现?


如何用Python将一个字典根据 key 值拆分成多个字典?

11 回复

collection defaultdict 了解一下


def split_dict_by_keys(original_dict, key_groups):
    """
    根据指定的key分组将字典拆分为多个子字典
    
    Args:
        original_dict: 原始字典
        key_groups: 包含多个key列表的列表,每个列表代表一个子字典需要的keys
    
    Returns:
        包含所有子字典的列表
    """
    result = []
    for keys in key_groups:
        sub_dict = {k: original_dict[k] for k in keys if k in original_dict}
        result.append(sub_dict)
    return result

# 使用示例
data = {'a': 1, 'b': 2, 'c': 3, 'd': 4, 'e': 5}
groups = [['a', 'b'], ['c', 'd', 'e']]

split_dicts = split_dict_by_keys(data, groups)
print(split_dicts)  # 输出: [{'a': 1, 'b': 2}, {'c': 3, 'd': 4, 'e': 5}]

# 如果某些key不存在,会自动跳过
groups2 = [['a', 'x'], ['b', 'c']]  # 'x'不存在
split_dicts2 = split_dict_by_keys(data, groups2)
print(split_dicts2)  # 输出: [{'a': 1}, {'b': 2, 'c': 3}]

这个函数的核心是字典推导式,遍历每个key组,只保留原始字典中存在的key。如果你想要更灵活的方式,比如按条件动态分组,可以这样:

def split_dict_by_condition(original_dict, condition_func):
    """
    根据条件函数拆分字典
    
    Args:
        condition_func: 接收key和value的函数,返回分组标识
    """
    from collections import defaultdict
    
    result = defaultdict(dict)
    for key, value in original_dict.items():
        group_id = condition_func(key, value)
        result[group_id][key] = value
    
    return list(result.values())

# 示例:按key的类型分组
data = {'a': 1, 'b': 2, 'c1': 3, 'd2': 4}
split_by_type = split_dict_by_condition(data, lambda k, v: '字母' if k.isalpha() else '数字')
print(split_by_type)  # [{'a': 1, 'b': 2}, {'c1': 3, 'd2': 4}]

用字典推导式按key分组最直接。

b={{}}
for key,value in a.items():
b[key[:2][key]]=value

>>> a = { ‘0106’: ‘50’, ‘0117’: ‘35’, ‘0203’: ‘30’, ‘0205’: ‘30’, ‘3302’: ‘45’, ‘3305’: ‘45’ }
>>> from itertools import groupby
>>> {k:dict(g) for k,g in groupby(sorted(a.items(), key=lambda x:x[0]), key=lambda x:x[0][:2])}
{‘01’: {‘0106’: ‘50’, ‘0117’: ‘35’}, ‘02’: {‘0203’: ‘30’, ‘0205’: ‘30’}, ‘33’: {‘3302’: ‘45’, ‘3305’: ‘45’}}

>>> a
{‘0117’: ‘35’, ‘0106’: ‘50’, ‘0205’: ‘30’, ‘0203’: ‘30’, ‘3305’: ‘45’, ‘3302’: ‘45’}
>>> {k[:2]: {i:j for i, j in a.items() if i.startswith(k[:2])} for k, _ in a.items()}
{‘02’: {‘0205’: ‘30’, ‘0203’: ‘30’}, ‘33’: {‘3305’: ‘45’, ‘3302’: ‘45’}, ‘01’: {‘0106’: ‘50’, ‘0117’: ‘35’}}

讲真写出来以后我并不觉得优雅:
>>> groupby_res = groupby(my_dict, lambda e: e[0:2])
>>>res = dict([(mini_key, dict([(key, my_dict[key]) for key in my_dict.keys() if key.startswith(mini_key)])) for mini_key, group in groupby_res for key in group])
>>> print(res)
>>> {‘01’: {‘0106’: ‘50’, ‘0117’: ‘35’}, ‘02’: {‘0203’: ‘30’, ‘0205’: ‘30’}, ‘33’: {‘3302’: ‘45’, ‘3305’: ‘45’}}

个人感觉最好还是写得明确一点,分多步构造也没关系。

from collections import defaultdict
ret = defaultdict(dict)
for k,v in a.items():
ret[k[:2]].update({k:v})

能写出来都是大神,至少我自己写不出来

from itertools import group_by
b = {k: dict(v) for k, v in groupby(list(a.items()), lambda item: item[0][:2])

from itertools import group_by
{k: dict(v) for k, v in groupby(a.items(), lambda item: item[0][:2])}

result = {}
for i in a:
if i[:2] not in result:
result[i[:2]] = {i : a[i]}
else:
result[i[:2]][i] = a[i]

回到顶部