Python列表去重復(fù)項的N種方法(實例代碼)
說明
Python語言中列表(List)與其他語言的數(shù)組(Array)類似,是一種有序的集合數(shù)據(jù)結(jié)構(gòu),Python List可支持各種數(shù)據(jù)類型,長度也可動態(tài)調(diào)整,與JS中的數(shù)組或Java ArrayList很接近。在實際編程中,經(jīng)常會遇到數(shù)組或列表去掉重復(fù)項,保持成員唯一性。實現(xiàn)方式有多種,比如新建列表來存儲非重復(fù)項,或者在原有基礎(chǔ)上刪除掉重復(fù)的項,也可以利用數(shù)據(jù)結(jié)構(gòu)來達到去重復(fù)。具體哪一種方法更好呢?以下約20種方式都可以實現(xiàn),我們可以通過這些來交流和學(xué)習(xí)。
方式
## 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. 新建列表。根據(jù)下標判斷是否存在新列表中,如果新列表中不存在則添加到新列表。
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 新建列表,使用列表推導(dǎo)來去重。是前一種的簡寫。
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. 新建列表,兩個循環(huán)。如果內(nèi)循環(huán)與外循環(huán)項相同,且下標相同就添加到新列表,其余忽略
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. 在原有列表上移除重復(fù)項目。自后往前遍歷,逐個與前面項比較,如果值相同且下標相同,則移除當前項。
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. 在原有列表上移除重復(fù)項目。自前往后遍歷,逐個與后面項比較,如果值相同且下標相同,則移除當前項。
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比較出現(xiàn)的位置,如果出現(xiàn)在第一次的位置則追加到新數(shù)組。
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. 利用字典屬性唯一性來實現(xiàn)去重復(fù)。
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來實現(xiàn)
print("dict fromkeys:", dict.fromkeys(data).keys())
## 9. 利用filter函數(shù),即把不符合條件的過濾掉。這里filter不支持下標,因此需要借助外部列表存儲不重復(fù)項
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. 利用字典結(jié)合過濾來實現(xiàn)去重復(fù)。
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來實現(xiàn)去重復(fù)。與map與filter類似,是一個高階函數(shù)。可以針對其中項逐個修改操作。
## 與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數(shù)據(jù)結(jié)構(gòu)里key的唯一性來去重復(fù)
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. 提前排序,從后向前遍歷,將當前項與前一項對比,如果重復(fù)則移除當前項
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. 提前排序,自前往后遍歷,將當前項與后一項對比,如果重復(fù)則移除當前項
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函數(shù)來去重復(fù)。reduce具有累計的作用,判斷如果不在累計結(jié)果中出現(xiàn),則追加到結(jié)果中。
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. 利用遞歸調(diào)用來去重復(fù)。遞歸自后往前逐個調(diào)用,當長度為1時終止。
## 當后一項與前任一項相同說明有重復(fù),則刪除當前項。相當于利用自我調(diào)用來替換循環(huán)
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. 利用遞歸調(diào)用來去重復(fù)的另外一種方式。遞歸自后往前逐個調(diào)用,當長度為1時終止。
## 與上一個遞歸不同,這里將不重復(fù)的項目作為結(jié)果拼接起來
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如此流行的原因吧。
哪一種方式更適合呢?你常用那種方式來實現(xiàn)去重復(fù)項?新建數(shù)組、非新建、借助Dict或Set等結(jié)構(gòu),亦或是其它方式?

總結(jié)
到此這篇關(guān)于Python列表去重復(fù)項的N種方法的文章就介紹到這了,更多相關(guān)python列表去重復(fù)項內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
pytorch通過自己的數(shù)據(jù)集訓(xùn)練Unet網(wǎng)絡(luò)架構(gòu)
Unet是一個最近比較火的網(wǎng)絡(luò)結(jié)構(gòu)。它的理論已經(jīng)有很多大佬在討論了。本文主要從實際操作的層面,講解如何使用pytorch實現(xiàn)unet圖像分割2022-12-12
詳解python異步編程之a(chǎn)syncio(百萬并發(fā))
這篇文章主要介紹了詳解python異步編程之a(chǎn)syncio(百萬并發(fā)),小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2018-07-07
Python利用psutil庫進行監(jiān)控進程和資源
psutil是Python系統(tǒng)和進程工具庫,它提供了一種跨平臺的方式來獲取系統(tǒng)信息、管理系統(tǒng)進程、監(jiān)控系統(tǒng)性能、操作系統(tǒng)資源等,下面就跟隨小編一起來學(xué)習(xí)psutil庫的具體應(yīng)用吧2024-01-01

