Python列表去重复项的N种方法(实例代码)
作者:刀法如飞 发布时间:2023-06-27 16:00:20
标签:python,列表,重复项
说明
Python语言中列表(List)与其他语言的数组(Array)类似,是一种有序的集合数据结构,Python List可支持各种数据类型,长度也可动态调整,与JS中的数组或Java ArrayList很接近。在实际编程中,经常会遇到数组或列表去掉重复项,保持成员唯一性。实现方式有多种,比如新建列表来存储非重复项,或者在原有基础上删除掉重复的项,也可以利用数据结构来达到去重复。具体哪一种方法更好呢?以下约20种方式都可以实现,我们可以通过这些来交流和学习。
方式
## 1. 新建列表,如果新列表中不存在,则添加到新列表。
def unique(data):
new_list = []
for item in data:
if item not in new_list:
new_list.append(item)
return new_list
# test
data = ['a', 'a', 1, 1, 2, 2, 'b', 'b', 2, 1]
start_time = time.time()
print("new_list + not in data:", unique(data))
print("time:" + str((time.time() - start_time) * 1000) + " ms")
# result
$ python -V
Python 2.7.16
$ python unique.py
('for list + not in. data:', ['a', 1, 2, 'b'])
time:0.0441074371338 ms
## 2. 新建列表。根据下标判断是否存在新列表中,如果新列表中不存在则添加到新列表。
def unique(data):
new_list = []
for i in range(len(data)):
if data[i] not in new_list:
new_list.append(data[i])
return new_list
## 2.1 新建列表,使用列表推导来去重。是前一种的简写。
def unique(data):
new_list = []
[new_list.append(i) for i in data if not i in new_list]
return new_list
# test
data = ['a', 'a', 1, 1, 2, 2, 'b', 'b', 2, 1]
start_time = time.time()
print("for range + not in. data:", unique(data))
print("time:" + str((time.time() - start_time) * 1000) + " ms")
## 3. 通过index找不到该项,则追加到新列表中。index找不到会报错,因此放在异常处理里。
def unique(data):
new_list = []
for i in range(len(data)):
item = data[i]
try:
if (new_list.index(item) < 0):
print('new_list:', new_list)
except ValueError:
new_list.append(item)
return new_list
# test
data = ['a', 'a', 1, 1, 2, 2, 'b', 'b', 2, 1]
start_time = time.time()
print("list index + except:", unique(data))
print("time:" + str((time.time() - start_time) * 1000) + " ms")
## 4. 新建列表,两个循环。如果内循环与外循环项相同,且下标相同就添加到新列表,其余忽略
def unique(data):
new_list = []
for i in range(len(data)):
j = 0
while j <= i:
if data[i] == data[j]:
if i == j:
new_list.append(data[i])
break
j += 1
return new_list
# test
data = ['a', 'a', 1, 1, 2, 2, 'b', 'b', 2, 1]
start_time = time.time()
print("new list + for. new_list:", unique(data))
print("time:" + str((time.time() - start_time) * 1000) + " ms")
## 5. 在原有列表上移除重复项目。自后往前遍历,逐个与前面项比较,如果值相同且下标相同,则移除当前项。
def unique(data):
l = len(data)
while (l > 0):
l -= 1
i = l
while i > 0:
i -= 1
if data[i] == data[l]:
del data[l]
break
return data
# test
data = ['a', 'a', 1, 1, 2, 2, 'b', 'b', 2, 1]
start_time = time.time()
print("one list while. last -> first result. data:", unique(data))
print("time:" + str((time.time() - start_time) * 1000) + " ms")
## 6. 在原有列表上移除重复项目。自前往后遍历,逐个与后面项比较,如果值相同且下标相同,则移除当前项。
def unique(data):
l = len(data)
i = 0
while i < l:
j = i + 1
while j < l:
if data[i] == data[j]:
del data[j]
l -= 1
i -= 1
break
j += 1
i += 1
return data
# test
data = ['a', 'a', 1, 1, 2, 2, 'b', 'b', 2, 1]
start_time = time.time()
print("one list while. first -> last result. data:", unique(data))
print("time:" + str((time.time() - start_time) * 1000) + " ms")
## 7. 新建列表。遍历列表,利用index比较出现的位置,如果出现在第一次的位置则追加到新数组。
def unique(data):
new_list = []
for i in range(len(data)):
if i == data.index(data[i]):
new_list.append(data[i])
return new_list
# test
data = ['a', 'a', 1, 1, 2, 2, 'b', 'b', 2, 1]
start_time = time.time()
print("for range + index. data:", unique(data))
print("time:" + str((time.time() - start_time) * 1000) + " ms")
## 8. 利用字典属性唯一性来实现去重复。
def unique(data):
obj = {}
for item in data:
obj[item] = item
return obj.values()
# test
data = ['a', 'a', 1, 1, 2, 2, 'b', 'b', 2, 1]
start_time = time.time()
print("list + dict:", unique(data))
print("time:" + str((time.time() - start_time) * 1000) + " ms")
## 或者直接通过dict.fromkeys来实现
print("dict fromkeys:", dict.fromkeys(data).keys())
## 9. 利用filter函数,即把不符合条件的过滤掉。这里filter不支持下标,因此需要借助外部列表存储不重复项
def uniq(item):
i = data.index(item)
if (item not in new_list):
new_list.append(item)
return True
return False
def unique(item):
if obj.get(item) == None:
obj[item] = item
return True
return False
# test
data = ['a', 'a', 1, 1, 2, 2, 'b', 'b', 2, 1]
start_time = time.time()
new_list = []
print('filter + list + not in: ', filter(uniq, data))
print("time:" + str((time.time() - start_time) * 1000) + " ms")
## 10. 利用字典结合过滤来实现去重复。
def unique(item):
if obj.get(item) == None:
obj[item] = item
return True
return False
# test
data = ['a', 'a', 1, 1, 2, 2, 'b', 'b', 2, 1]
start_time = time.time()
obj = {}
print("filter + dict + get:", filter(unique, data))
print("time:" + str((time.time() - start_time) * 1000) + " ms")
## 11. 利用map来实现去重复。与map与filter类似,是一个高阶函数。可以针对其中项逐个修改操作。
## 与filter不同map会保留原有项目,并不会删除,因此值可以改为None,然后再过滤掉。
def unique(item):
if item not in new_list:
new_list.append(item)
return item
return None
# test
data = ['a', 'a', 1, 1, 2, 2, 'b', 'b', 2, 1]
new_list = []
start_time = time.time()
print("list from Map:", filter(lambda item: item != None, map(unique, data)))
print("time:" + str((time.time() - start_time) * 1000) + " ms")
## 12. 利用set数据结构里key的唯一性来去重复
data = ['a', 'a', 1, 1, 2, 2, 'b', 'b', 2, 1]
print("from Set:", list(set(data)))
print("time:" + str((time.time() - start_time) * 1000) + " ms")
## 13. 提前排序,从后向前遍历,将当前项与前一项对比,如果重复则移除当前项
def unique(data):
data.sort()
l = len(data)
while (l > 0):
l -= 1
if (data[l] == data[l - 1]):
data.remove(data[l])
return data
# test
data = ['a', 'a', 1, 1, 2, 2, 'b', 'b', 2, 1]
start_time = time.time()
print("sort + remove:", unique(data))
print("time:" + str((time.time() - start_time) * 1000) + " ms")
## 14. 提前排序,自前往后遍历,将当前项与后一项对比,如果重复则移除当前项
def unique(data):
"""
in python 3: TypeError: '<' not supported between instances of 'int' and 'str'
need to keep the same Type of member in List
"""
data.sort()
l = len(data) - 1
i = 0
while i < l:
if (data[i] == data[i + 1]):
del data[i]
i -= 1
l -= 1
i += 1
return data
# test
data = ['a', 'a', 1, 1, 2, 2, 'b', 'b', 2, 1]
start_time = time.time()
print("sort+del ASE:", unique(data))
print("time:" + str((time.time() - start_time) * 1000) + " ms")
## 15. 利用reduce函数来去重复。reduce具有累计的作用,判断如果不在累计结果中出现,则追加到结果中。
import functools
def unique(data):
new_list = []
def foo(result, item):
if isinstance(result, list) == False:
result = [result]
return result if item in result else result + [item]
return functools.reduce(foo, data)
# test
data = ['a', 'a', 1, 1, 2, 2, 'b', 'b', 2, 1]
start_time = time.time()
print("functools.reduce:", unique(data))
print("time:" + str((time.time() - start_time) * 1000) + " ms")
## 16. 利用递归调用来去重复。递归自后往前逐个调用,当长度为1时终止。
## 当后一项与前任一项相同说明有重复,则删除当前项。相当于利用自我调用来替换循环
def recursion_unique(data, len):
if (len <= 1):
return data
l = len
last = l - 1
is_repeat = False
while (l > 1):
l -= 1
if (data[last] == data[l - 1]):
is_repeat = True
break
if (is_repeat):
del data[last]
return recursion_unique(data, len - 1)
# test
data = ['a', 'a', 1, 1, 2, 2, 'b', 'b', 2, 1]
start_time = time.time()
print("recursion_unique:", recursion_unique(data, len(data)))
print("time:" + str((time.time() - start_time) * 1000) + " ms")
## 17. 利用递归调用来去重复的另外一种方式。递归自后往前逐个调用,当长度为1时终止。
## 与上一个递归不同,这里将不重复的项目作为结果拼接起来
def recursion_unique_new(data, len):
if (len <= 1):
return data
l = len
last = l - 1
is_repeat = False
while (l > 1):
l -= 1
if (data[last] == data[l - 1]):
is_repeat = True
break
if (is_repeat):
del data[last:]
result = []
else:
result = [data[last]]
return recursion_unique_new(data, len - 1) + result
# test
data = ['a', 'a', 1, 1, 2, 2, 'b', 'b', 2, 1]
start_time = time.time()
print("recursion_unique_new:", recursion_unique_new(data, len(data)))
print("time:" + str((time.time() - start_time) * 1000) + " ms")
## 18. 利用numpy lib库. 需提前安装 `pip install numpy`
import numpy as np
def unique(data):
res = np.array(data)
return list(np.unique(res))
# test
data = ['a', 'a', 1, 1, 2, 2, 'b', 'b', 2, 1]
start_time = time.time()
print("import numpy as np.unique:", unique(data))
print("time:" + str((time.time() - start_time) * 1000) + " ms")
讨论
从以上例子上可以看出,相对来讲,Python比起其它语言要灵活得多,与JS并列最流行的脚本类语言,这也就是为何Python如此流行的原因吧。
哪一种方式更适合呢?你常用那种方式来实现去重复项?新建数组、非新建、借助Dict或Set等结构,亦或是其它方式?
来源:http://developer.51cto.com/art/202005/616352.htm
0
投稿
猜你喜欢
- 呃,看到这个标题,我们可以首先将IE系浏览器无视了。我承认,我是有极简主义倾向的,我希望能够使用最少的代码和图片做更多的事情。虽然CSS3仅
- Oracle提供了不少方法用于数据空间的使用、监控和维护,同时也在各版本中陆续对这方面的功能进行了增强,目的在于简化这方面工作的复杂度,提高
- 因为自己在设计的时候就对这些东西经常不是很在意,以为是很小的事情,结果往往给自己搞出不少的麻烦。可能大家没有我这么粗心,不过还是想提醒一下跟
- 中间件中间件是放在客户端和服务端的中间。 当你的客户端对某个接口发起一个请求,但是在到达接口2之前,这里是有一层中间件的处理。一般
- 代码如下:'================================================== '函数名:
- 1. 用户必须在几秒钟知道网站是做什么的。注意力是因特网上最有价值的货币。 如果访问者无法在几秒钟之内得知你的网站的方向,他很有可能转而访问
- 1. 排序有什么用“排序”这个专业名词原本是来源于计算机程序操作中的,是一种很常见的算法设计,当然,对交互设计来说,探讨冒泡排序和堆排序之间
- SQL是用于访问ORACLE数据库的语言,PL/SQL扩展和加强了SQL的功能,它 同时引入了更强的程序逻辑。 PL/SQL支持DML命令和
- 以下是通过Excel 的VBA连接Oracle并操作Oracle相关数据的示例Excel 通过VBA连接数据库需要安装相应的Oracle客户
- 2009年 6月6日,空间4岁啦!与此同时Qzone月登录用户2亿,同时在线用户也突破了1000万。这是让人欢欣雀跃的数字,在空间同事眼里,
- 农历新年将至,支付宝红包打了一仗,微信在朋友圈屏蔽了它的分享,但单防守还不行,进攻才是最好的防守。昨日,微信支付现金红包接口正式开放,只需开
- 函数getcache,会自动建立需要的缓存。 代码如下:Function getcache(funsname,isreset,is
- 现在有一个xml,格式如下: <date> <item> <id> 1 </id> <
- JavaScript/Dom中有很多很零碎的东西,让人总是感觉理解的有些“朦胧”,因此,有时候还是应该总结一下,对于Event对象,前两天看
- 选择正确的数据列类型能大大提高数据库的性能和使数据库具有高扩展性。在选择数据列类型时,请从以下几个方面考虑:存放到数据列中的数据类型。数据值
- 显然,效果很实用。对于这个效果,我们并不解释如何去使用效果库,而是讲解如何创建类似的效果,并保持他的可用性,分离式(unobtrusive)
- 问题你想在使用范围内执行某个代码片段,并且希望在执行后所有的结果都不可见。解决方案为了理解这个问题,先试试一个简单场景。首先,在全局命名空间
- 看过数据库的备份与还原。大多数都是用组件来完成的。其实可通过sql语句来完成。 由于时间关系,未对参数进行验证和界面美化。代码
- Mysql数据库是一个多用户,多线程的关系型数据库,是一个客户机/服务器结构的应用程序。它是对个人用户和商业用户是免费的.Mysql数据库具
- using System; using System.Collections; using System.Configuration; us