Python数据结构去重操作汇总【收藏版】

文章目录

  • 1.列表去重
  • 1.1 使用集合去重
  • 1.2 保持顺序去重
  • 2.元组去重
  • 2.1 转换为集合去重
  • 2.2 保持顺序去重
  • 3 集合去重
  • 4 字典去重
  • 4.1 按键去重
  • 4.2 按值去重
  • 5 类实例去重
  • 5.1 使用集合去重
  • 6 嵌套数据结构去重
  • 6.1 嵌套列表去重
  • 6.2 嵌套列表去重的简便写法【常用】
  • 6.3 嵌套字典去重
  • 6.4 嵌套字典去重的简便写法【常用】
  • 6.5 嵌套集合去重
  • 7 使用第三方库去重
  • 7.1 Pandas去重
  • 8 嵌套数据结构去重
  • 8.1 使用 frozenset 处理嵌套列表
  • 9 基于键值对的复杂字典去重
  • 10 复杂嵌套数据结构去重
  • 11 自定义类去重
  • 拓展:字符串去重【不常用】
  • 1 使用集合去重并保持顺序
  • 2 使用集合去重但不保持顺序
  • 3 使用字典的 `fromkeys` 方法去重并保持顺序(Python 3.7+)
  • 4 使用 `collections.OrderedDict` 去重并保持顺序(适用于Python 3.6及以下版本)
  • 5 使用列表解析去重并保持顺序
  • 6 使用Pandas去重
  • 在 Python 中,去重是一个常见操作,特别是在处理数据结构时。以下是几种常见的数据结构的去重方法,包括列表、元组、集合和字典。此外,还会介绍嵌套数据结构的去重方法。

    1.列表去重

    1.1 使用集合去重

    lst = [1, 2, 2, 3, 4, 4, 5]
    unique_lst = list(set(lst))
    print(unique_lst)
    

    1.2 保持顺序去重

    lst = [1, 2, 2, 3, 4, 4, 5]
    unique_lst = []
    seen = set()
    for item in lst:
        if item not in seen:
            unique_lst.append(item)
            seen.add(item)
    print(unique_lst)
    

    2.元组去重

    2.1 转换为集合去重

    tup = (1, 2, 2, 3, 4, 4, 5)
    unique_tup = tuple(set(tup))
    print(unique_tup)
    

    2.2 保持顺序去重

    tup = (1, 2, 2, 3, 4, 4, 5)
    unique_tup = []
    seen = set()
    for item in tup:
        if item not in seen:
            unique_tup.append(item)
            seen.add(item)
    unique_tup = tuple(unique_tup)
    print(unique_tup)
    

    3 集合去重

    集合本身不允许重复元素:

    s = {1, 2, 2, 3, 4, 4, 5}
    print(s)
    

    4 字典去重

    4.1 按键去重

    d = {'a': 1, 'b': 2, 'c': 2, 'd': 3}
    unique_d = {k: v for k, v in d.items()}
    print(unique_d)
    

    4.2 按值去重

    d = {'a': 1, 'b': 1, 'c': 2, 'd': 3}
    unique_d = {k: v for k, v in d.items() if list(d.values()).count(v) == 1}
    print(unique_d)
    

    5 类实例去重

    5.1 使用集合去重

    假设我们有一个 Person 类,我们可以通过定义 __hash____eq__ 方法来使类的实例可被集合去重:

    class Person:
        def __init__(self, name, age):
            self.name = name
            self.age = age
    
        def __hash__(self):
            return hash((self.name, self.age))
    
        def __eq__(self, other):
            return (self.name, self.age) == (other.name, other.age)
    
        def __repr__(self):
            return f"Person(name={self.name}, age={self.age})"
    
    persons = [Person('Alice', 30), Person('Bob', 25), Person('Alice', 30)]
    unique_persons = list(set(persons))
    print(unique_persons)
    

    6 嵌套数据结构去重

    6.1 嵌套列表去重

    递归去重,保持嵌套结构的顺序:

    def unique_nested_list(lst):
        seen = set()
        unique_lst = []
        for item in lst:
            if isinstance(item, list):
                item = tuple(unique_nested_list(item))
            if item not in seen:
                seen.add(item)
                unique_lst.append(item)
        return unique_lst
    
    nested_lst = [[1, 2], [2, 3], [1, 2], [3, 4]]
    unique_nested_lst = unique_nested_list(nested_lst)
    print(unique_nested_lst)
    

    6.2 嵌套列表去重的简便写法【常用】

    nested_lst = [[1, 2], [2, 3], [1, 2], [3, 4]]
    unique_lst = [list(t) for t in {tuple(x) for x in nested_lst}]
    print(unique_lst)
    
    

    内层集合推导:{tuple(x) for x in nested_lst} 将每个子列表 x 转换为元组并去重。
    外层列表推导:[list(t) for t in unique_set] 将去重后的元组转换回列表。

    6.3 嵌套字典去重

    递归去重,包括字典的键和值:

    def unique_nested_dict(d):
        seen = set()
        unique_dict = {}
        for k, v in d.items():
            if isinstance(v, dict):
                v = tuple(sorted(unique_nested_dict(v).items()))
            elif isinstance(v, list):
                v = tuple(unique_nested_list(v))
            if (k, v) not in seen:
                seen.add((k, v))
                unique_dict[k] = v
        return unique_dict
    
    def unique_nested_list(lst):
        seen = set()
        unique_lst = []
        for item in lst:
            if isinstance(item, dict):
                item = tuple(sorted(unique_nested_dict(item).items()))
            elif isinstance(item, list):
                item = tuple(unique_nested_list(item))
            if item not in seen:
                seen.add(item)
                unique_lst.append(item)
        return unique_lst
    
    nested_dict = {
        'a': {'b': 1, 'c': 2},
        'd': {'b': 1, 'c': 2},
        'e': {'f': 3}
    }
    unique_nested_dict = unique_nested_dict(nested_dict)
    print(unique_nested_dict)
    

    6.4 嵌套字典去重的简便写法【常用】

    import json
    
    nested_dicts = [
        {'a': 1, 'b': {'c': 2, 'd': 3}},
        {'a': 1, 'b': {'c': 2, 'd': 3}},
        {'a': 2, 'b': {'c': 3, 'd': 4}}
    ]
    
    # 将字典转换为 JSON 字符串,然后去重
    unique_dicts = list({json.dumps(d, sort_keys=True) for d in nested_dicts})
    # 将 JSON 字符串转换回字典
    unique_dicts = [json.loads(d) for d in unique_dicts]
    
    print(unique_dicts)
    

    解析

    1.转换为 JSON 字符串:
    使用 json.dumps(d, sort_keys=True) 将字典转换为 JSON 字符串,并且 sort_keys=True 确保字典中的键按顺序排列,从而确保相同的字典生成相同的字符串。
    2.集合去重:
    使用集合 {…} 对 JSON 字符串进行去重,因为字符串是不可变的,可以直接用来去重。
    3.转换回字典:
    使用 json.loads(d) 将去重后的 JSON 字符串转换回字典。

    6.5 嵌套集合去重

    处理嵌套集合时,利用 frozenset 来实现不可变集合的去重。

    nested_sets = [{1, 2}, {2, 3}, {1, 2}, {4, 5}]
    unique_sets = list(set(frozenset(s) for s in nested_sets))
    print(unique_sets)
    

    7 使用第三方库去重

    7.1 Pandas去重

    Pandas库在处理数据框时提供了强大的去重功能。

    import pandas as pd
    
    df = pd.DataFrame({'A': [1, 2, 2, 3], 'B': [4, 5, 5, 6]})
    unique_df = df.drop_duplicates()
    print(unique_df)
    

    8 嵌套数据结构去重

    8.1 使用 frozenset 处理嵌套列表

    对于嵌套列表,可以利用 frozenset 来处理不可变集合的情况。

    def unique_nested_list(lst):
        def make_frozenset(item):
            if isinstance(item, list):
                return frozenset(make_frozenset(sub_item) for sub_item in item)
            return item
    
        unique_set = set(make_frozenset(item) for item in lst)
        
        def make_list(item):
            if isinstance(item, frozenset):
                return [make_list(sub_item) for sub_item in item]
            return item
    
        unique_lst = [make_list(item) for item in unique_set]
        return unique_lst
    
    nested_lst = [[1, 2], [2, 3], [1, 2], [3, 4]]
    unique_nested_lst = unique_nested_list(nested_lst)
    print(unique_nested_lst)
    
    

    9 基于键值对的复杂字典去重

    对于复杂的字典,可以通过自定义哈希和比较函数来处理。

    def unique_complex_dict(dicts):
        class DictWrapper:
            def __init__(self, d):
                self.d = d
            
            def __hash__(self):
                return hash(frozenset(self.d.items()))
            
            def __eq__(self, other):
                return self.d == other.d
            
        unique_dicts = list(set(DictWrapper(d) for d in dicts))
        return [dw.d for dw in unique_dicts]
    
    dicts = [
        {'a': 1, 'b': 2},
        {'b': 2, 'a': 1},
        {'a': 2, 'b': 3}
    ]
    unique_dicts = unique_complex_dict(dicts)
    print(unique_dicts)
    

    10 复杂嵌套数据结构去重

    结合各种数据结构处理复杂的嵌套情况。

    def recursive_unique(data):
        if isinstance(data, list):
            return list(map(recursive_unique, set(map(tuple, data))))
        elif isinstance(data, dict):
            return {k: recursive_unique(v) for k, v in data.items()}
        elif isinstance(data, set):
            return set(map(recursive_unique, data))
        else:
            return data
    
    nested_structure = {
        'a': [{'x': 1, 'y': 2}, {'x': 1, 'y': 2}, {'x': 3, 'y': 4}],
        'b': {frozenset([1, 2]), frozenset([1, 2]), frozenset([3, 4])}
    }
    
    unique_nested_structure = recursive_unique(nested_structure)
    print(unique_nested_structure)
    

    11 自定义类去重

    为自定义类提供更加复杂的去重逻辑。

    class CustomObject:
        def __init__(self, id, name, value):
            self.id = id
            self.name = name
            self.value = value
        
        def __hash__(self):
            return hash((self.id, self.name))
        
        def __eq__(self, other):
            return self.id == other.id and self.name == other.name
        
        def __repr__(self):
            return f"CustomObject(id={self.id}, name={self.name}, value={self.value})"
    
    objs = [
        CustomObject(1, 'Alice', 100),
        CustomObject(2, 'Bob', 200),
        CustomObject(1, 'Alice', 300)
    ]
    unique_objs = list(set(objs))
    print(unique_objs)
    

    拓展:字符串去重【不常用】

    在Python中,可以通过多种方式对字符串进行去重。以下是几种常见的方法:

    1 使用集合去重并保持顺序

    def unique_string(s):
        seen = set()
        return ''.join(seen.add(c) or c for c in s if c not in seen)
    
    s = "banana"
    unique_s = unique_string(s)
    print(unique_s)  # 输出: "ban"
    

    2 使用集合去重但不保持顺序

    s = "banana"
    unique_s = ''.join(set(s))
    print(unique_s)  # 输出可能是: "abn"(顺序不固定)
    

    3 使用字典的 fromkeys 方法去重并保持顺序(Python 3.7+)

    s = "banana"
    unique_s = ''.join(dict.fromkeys(s))
    print(unique_s)  # 输出: "ban"
    

    4 使用 collections.OrderedDict 去重并保持顺序(适用于Python 3.6及以下版本)

    from collections import OrderedDict
    
    s = "banana"
    unique_s = ''.join(OrderedDict.fromkeys(s))
    print(unique_s)  # 输出: "ban"
    

    5 使用列表解析去重并保持顺序

    s = "banana"
    unique_s = ''.join([c for i, c in enumerate(s) if c not in s[:i]])
    print(unique_s)  # 输出: "ban"
    

    6 使用Pandas去重

    import pandas as pd
    
    s = "banana"
    unique_s = ''.join(pd.Series(list(s)).drop_duplicates().tolist())
    print(unique_s)  # 输出: "ban"
    

    这些方法中,前三种是最常用的,特别是第一种和第三种,能够保持字符的原始顺序。如果你对顺序没有要求,可以使用第二种方法,它更简单直接。

    作者:今晚务必早点睡

    物联沃分享整理
    物联沃-IOTWORD物联网 » Python数据结构去重操作汇总【收藏版】

    发表回复