Python中如何高效清洗列表和字典数据?

有一个列表字典是这样的

l = [{‘name’: ‘aa’, ‘type’: ‘游戏’}, {‘name’: ‘bb’, ‘type’: ‘游戏’}, {‘name’: ‘cc’, ‘type’: ‘学习’}]

类似上述的列表包括含有类型的键的字典,如何过滤掉和大部分类型不一样的字典

比如列表中一共有 8 个字典,6 个字典中类型是游戏,1 个字典中类型是学习,还有个字典中类型是玩耍,如何过滤后面两个

当然类型是不确定的,数量多的不一定是游戏,还可能是吃饭。。或睡觉

有木有大佬给思路
Python中如何高效清洗列表和字典数据?


10 回复

统计每个类型出现的百分比,然后根据 Zipf’s Law 选一个阈值删掉百分比小的类型。


def clean_list(data_list, remove_values=[None, '', 0], deduplicate=True):
    """
    清洗列表数据
    
    参数:
    data_list: 待清洗的列表
    remove_values: 需要移除的值列表,默认移除None、空字符串和0
    deduplicate: 是否去重,默认为True
    
    返回:
    清洗后的列表
    """
    # 移除指定值
    cleaned = [item for item in data_list if item not in remove_values]
    
    # 去重(保持顺序)
    if deduplicate:
        seen = set()
        cleaned = [item for item in cleaned if not (item in seen or seen.add(item))]
    
    return cleaned

def clean_dict(data_dict, remove_keys=[], remove_values=[None, '', 0], deep_clean=False):
    """
    清洗字典数据
    
    参数:
    data_dict: 待清洗的字典
    remove_keys: 需要移除的键列表
    remove_values: 需要移除的值列表
    deep_clean: 是否深度清洗嵌套结构
    
    返回:
    清洗后的字典
    """
    cleaned = {}
    
    for key, value in data_dict.items():
        # 跳过需要移除的键
        if key in remove_keys:
            continue
            
        # 深度清洗嵌套结构
        if deep_clean:
            if isinstance(value, list):
                value = clean_list(value, remove_values)
            elif isinstance(value, dict):
                value = clean_dict(value, remove_keys, remove_values, deep_clean)
        
        # 跳过需要移除的值
        if value not in remove_values:
            cleaned[key] = value
    
    return cleaned

# 使用示例
if __name__ == "__main__":
    # 测试列表清洗
    dirty_list = [1, 2, None, 3, '', 2, 0, 4]
    print("原始列表:", dirty_list)
    print("清洗后:", clean_list(dirty_list))
    
    # 测试字典清洗
    dirty_dict = {
        'name': 'Alice',
        'age': None,
        'scores': [85, None, 90, 0, 85],
        'empty': '',
        'nested': {'a': 1, 'b': None, 'c': [None, 2]}
    }
    print("\n原始字典:", dirty_dict)
    print("清洗后:", clean_dict(dirty_dict, deep_clean=True))

核心思路就是通过列表推导式和字典推导式进行过滤,配合递归处理嵌套结构。对于列表主要处理空值和去重,字典则处理无效键值对和嵌套数据。

建议:根据实际数据特点调整移除的值列表。

数据少的话:
lst = sorted(l, key=(lambda x : x.get(‘type’)))
ret = [[]]
for prv, nxt in zip(lst[:-1], lst[1:]):
…tmp = ret[-1]
…tmp.append(prv)
…if prv[‘type’]!=nxt[‘type’]:
…ret.append([])
tmp = ret[-1]
tmp.append(t[-1])
然后取 ret 里最多的,或者直接用 groupby
[ list(g) for c, g in groupby(lst, key=(lambda x : x.get(‘type’))) ]
但是都需要排序。

或者用 pandas:
import pandas as pd
l= [{‘name’: ‘aa’, ‘type’: ‘游戏’},
{‘name’: ‘cc’, ‘type’: ‘学习’},
{‘name’: ‘bb’, ‘type’: ‘游戏’}] # 可以不用考虑顺序

list(pd.DataFrame(l).groupby(‘type’)) 可以搞定,输出是 n 个 categories 的 tuple 的 list

[(分组名 1,分组 1 数据的 dataframe),(分组名 2,分组 2 数据的 dataframe)…],数据大小可以用 dataframe 的 shape 来确定。

In [40]: list(pd.DataFrame(l).groupby(‘type’))
Out[40]:
[(‘学习’, name type
1 cc 学习), (‘游戏’, name type
0 aa 游戏
2 bb 游戏)]

In [41]: p=list(pd.DataFrame(l).groupby(‘type’))[1][1]

In [42]: p.shape
Out[42]: (2, 2)

In [43]: p
Out[43]:
name type
0 aa 游戏
2 bb 游戏

对一定量的数据,pandas 就可以有很高的处理效率了,如果数据量再大,考虑上 #1 的方法吧。

从第一步我就没想到好方法来统计每个类型出现的百分比

from itertools import groupby
[ list(g) for c, g in groupby(lst, key=(lambda x : x.get(‘type’))) ]

百分比很好统计:

ret = {}
for i in l:
…if not ret.get(i[‘type’]):
…ret[i[‘type’]] = 0
…ret.get(i[‘type’]) +=1

基本上在不知道 type 有多少的情况下也能轻松统计

Sorry,

ret = {}
for i in l:
…if not ret.get(i[‘type’]):
…ret[i[‘type’]] = 0
…ret[i[‘type’]] +=1

谢谢,这个帮大忙了[ list(g) for c, g in groupby(lst, key=(lambda x : x.get(‘type’))) ]



额。。如果 l 变成[{‘name’: ‘aa’, ‘type’: ‘游戏’}, {‘name’: ‘bb’, ‘type’: ‘游戏’}, {‘name’: ‘cc’, ‘type’: ‘学习’}, {‘name’: ‘dd’, ‘type’: ‘游戏’}]

用这个[list(g) for c,g in groupby(l, key=(lambda x: x.get(‘type’)))]居然会拆开他们

输出[[{‘name’: ‘aa’, ‘type’: ‘游戏’}, {‘name’: ‘bb’, ‘type’: ‘游戏’}], [{‘name’: ‘cc’, ‘type’: ‘学习’}], [{‘name’: ‘dd’, ‘type’: ‘游戏’}]]

这就是我不想要的结果了,我还是看看 pandas 中的 group_by

我在 #2 已经说了,这个需要先排序。pandas 可以无视顺序。所以数据量小考虑直接 python sorted + itertools.groupby,数据量大一些考虑 pandas.DataFrame.groupby,如果超超超大就考虑 #1 的办法。

回到顶部