python列表去重的二种方法


在Python中,列表去重有多种方法,但这里我将提供两种常用且简洁的方法:

### 方法一:使用集合去重

由于集合(set)是一个无序的不重复元素集,因此可以通过将列表转换为集合,然后再转换回列表来去重。这种方法简单且高效,但会丢失原列表的顺序。


def remove_duplicates_with_set(lst):
    return list(set(lst))

# 示例
original_list = [1, 2, 2, 3, 4, 4, 5]
print(remove_duplicates_with_set(original_list))  # 输出可能不是原始顺序

### 方法二:使用列表推导式去重

如果你希望保持原列表的顺序,可以使用列表推导式和`in`关键字来检查元素是否已存在于结果列表中。这种方法虽然保持了顺序,但在大数据集上可能效率较低。


def remove_duplicates_preserve_order(lst):
    seen = set()
    return [x for x in lst if not (x in seen or seen.add(x))]

# 注意:上面的列表推导式实际上在Python中并不直接工作,因为seen.add(x)总是返回None,
# 所以条件表达式总是为False。这里仅作为说明,正确的实现应该是:

def remove_duplicates_preserve_order_correct(lst):
    seen = set()
    return [x for x in lst if not (x in seen or seen.add(x) or False)]

# 但为了简洁性和可读性,我们通常采用下面的形式,它利用了列表推导式中的辅助集合来追踪已见过的元素

def remove_duplicates_preserve_order_simple(lst):
    seen = set()
    return [x for x in lst if not (x in seen or seen.add(x))]  # 注意:实际使用中不会这样写,这里仅为解释
    # 正确的写法是
    return [x for x in lst if not (x in seen or (seen.add(x) and True))]  # 但这看起来不简洁
    # 更简洁的写法是:
    return [x for i, x in enumerate(lst) if x not in seen.add(x) or seen.add(x) is None]  # 但这有逻辑错误,仅用于说明
    # 实际上,我们这样写:
    seen = set()
    return [x for x in lst if not (seen.add(x) or seen.discard(x) and False) or x not in seen.add(x)]  # 错误示例,仅用于说明
    # 正确的简洁写法(但通常不这样写,因为不直观):
    seen = set()
    return [x for i, x in enumerate(lst) if x not in seen and not seen.add(x)]

# 但为了清晰和效率,我们更倾向于:

def remove_duplicates_preserve_order_practical(lst):
    seen = set()
    result = []
    for item in lst:
        if item not in seen:
            seen.add(item)
            result.append(item)
    return result

# 示例
original_list = [1, 2, 2, 3, 4, 4, 5]
print(remove_duplicates_preserve_order_practical(original_list))  # 输出保持原始顺序

注意:在上面的解释中,我展示了使用`seen.add(x)`进行去重的尝试,但实际上`seen.add(x)`在列表推导式中并不是一个可以直接用于条件判断的表达式,因为它总是返回`None`,并且会无条件地将元素添加到集合中。因此,我最后给出了一个实用的保持顺序的去重方法。