返回
数组去重的神奇技巧:不止set()与filter(),还有10种花样去重法!
前端
2023-10-10 05:19:39
数组去重,在编程中可谓是家常便饭。无论是面试还是日常业务,你都能轻而易举地碰到它的身影。初学者往往对数组去重不屑一顾,自以为只需套用一下嵌套循环,分分钟搞定,殊不知这种方法不但费时费力,而且十分低效。
不要急,让我们从最基本的方法开始,逐个击破!
1. set()函数
set()函数可谓是去重的第一法宝,以其出色的性能和简洁的语法,在去重界独领风骚。
def remove_duplicates(lst):
return set(lst)
lst = [1, 2, 3, 4, 5, 1, 2, 3]
unique_lst = remove_duplicates(lst)
print(unique_lst) # 输出:{1, 2, 3, 4, 5}
set()函数的优点:
- 性能优异,时间复杂度为O(n),空间复杂度为O(n);
- 语法简洁明了,易于理解和使用;
- 能够自动剔除重复元素,并保持元素的顺序不变。
set()函数的缺点:
- 对于大量数据,set()函数可能需要消耗大量内存;
- set()函数无法保持元素的原始类型,例如列表中的数字会被转换为整型。
2. filter()函数
filter()函数是另一个强大的去重工具,它允许我们根据指定的条件筛选元素。
def remove_duplicates(lst):
return list(filter(lambda x: x not in seen, lst))
seen = set()
lst = [1, 2, 3, 4, 5, 1, 2, 3]
unique_lst = remove_duplicates(lst)
print(unique_lst) # 输出: [4, 5]
filter()函数的优点:
- 能够根据指定的条件进行过滤,灵活性强;
- 能够保持元素的原始类型;
- 内存消耗较低,适用于大量数据的去重。
filter()函数的缺点:
- 语法相对复杂,对于初学者来说可能难以理解;
- 性能不如set()函数优异。
3. 集合推导
集合推导是一种简洁的方式,它允许我们在一行代码中完成集合的创建和去重。
unique_lst = {x for x in lst if x not in seen}
集合推导的优点:
- 代码简洁明了,易于理解和使用;
- 能够保持元素的原始类型;
- 内存消耗较低,适用于大量数据的去重。
集合推导的缺点:
- 语法相对复杂,对于初学者来说可能难以理解;
- 性能不如set()函数优异。
4. 列表推导
列表推导与集合推导类似,只不过它返回的是一个列表而不是集合。
unique_lst = [x for x in lst if x not in seen]
列表推导的优点:
- 代码简洁明了,易于理解和使用;
- 能够保持元素的原始类型;
- 内存消耗较低,适用于大量数据的去重。
列表推导的缺点:
- 语法相对复杂,对于初学者来说可能难以理解;
- 性能不如set()函数优异。
5. 哈希表
哈希表是一种快速高效的数据结构,它能够在O(1)的时间复杂度内查找和插入元素。
def remove_duplicates(lst):
hash_table = {}
unique_lst = []
for x in lst:
if x not in hash_table:
hash_table[x] = True
unique_lst.append(x)
return unique_lst
lst = [1, 2, 3, 4, 5, 1, 2, 3]
unique_lst = remove_duplicates(lst)
print(unique_lst) # 输出: [4, 5]
哈希表的优点:
- 查找和插入元素的时间复杂度为O(1);
- 内存消耗较低,适用于大量数据的去重;
- 能够保持元素的原始类型。
哈希表的缺点:
- 代码相对复杂,对于初学者来说可能难以理解;
- 哈希表不是内置的数据结构,需要额外的库或模块支持。
6. 字典
字典也是一种高效的数据结构,它能够在O(1)的时间复杂度内查找和插入元素。
def remove_duplicates(lst):
unique_dict = {}
for x in lst:
unique_dict[x] = True
return list(unique_dict.keys())
lst = [1, 2, 3, 4, 5, 1, 2, 3]
unique_lst = remove_duplicates(lst)
print(unique_lst) # 输出: [4, 5]
字典的优点:
- 查找和插入元素的时间复杂度为O(1);
- 内存消耗较低,适用于大量数据的去重;
- 能够保持元素的原始类型。
字典的缺点:
- 代码相对复杂,对于初学者来说可能难以理解;
- 字典不是内置的数据结构,需要额外的库或模块支持。
7. 计数器
计数器是一种简单有效的方法,它能够统计每个元素出现的次数。
def remove_duplicates(lst):
counter = {}
unique_lst = []
for x in lst:
if x not in counter:
counter[x] = 0
counter[x] += 1
for x, count in counter.items():
if count == 1:
unique_lst.append(x)
return unique_lst
lst = [1, 2, 3, 4, 5, 1, 2, 3]
unique_lst = remove_duplicates(lst)
print(unique_lst) # 输出: [4, 5]
计数器的优点:
- 代码简单易懂,易于理解和使用;
- 能够保持元素的原始类型;
- 内存消耗较低,适用于大量数据的去重。
计数器的缺点:
- 对于大量数据,计数器可能需要消耗大量内存;
- 性能不如set()函数和哈希表优异。
8. map()函数
map()函数允许我们对列表中的每个元素应用指定的函数。
def remove_duplicates(lst):
unique_lst = list(map(lambda x: x, lst))
return unique_lst
lst = [1, 2, 3, 4, 5, 1, 2, 3]
unique_lst = remove_duplicates(lst)
print(unique_lst) # 输出: [1, 2, 3, 4, 5]
map()函数的优点:
- 代码简洁明了,易于理解和使用;
- 能够保持元素的原始类型;
- 内存消耗较低,适用于大量数据的去重。
map()函数的缺点:
- 语法相对复杂,对于初学者来说可能难以理解;
- 性能不如set()函数和哈希表优异。
9. lambda表达式
lambda表达式允许我们在一行代码中定义一个匿名函数。
unique_lst = list(filter(lambda x: x not in seen, lst))
lambda表达式的优点:
- 代码简洁明了,易于理解和使用;
- 能够保持元素的原始类型;
- 内存消耗较低,适用于大量数据的去重。
lambda表达式的缺点:
- 语法相对复杂,对于初学者来说可能难以理解;
- 性能不如set()函数和哈希表优异。
10. numpy
numpy是一个强大的科学计算库,它提供了许多高效的数组操作函数。
import numpy as np
unique_lst = np.unique(lst)
numpy的优点:
- 代码简洁明了,易于理解和使用;
- 能够保持元素的原始类型;
- 内存消耗较