我如何检查一个列表是否有任何重复,并返回一个没有重复的新列表?
当前回答
尝试使用集合:
import sets
t = sets.Set(['a', 'b', 'c', 'd'])
t1 = sets.Set(['a', 'b', 'c'])
print t | t1
print t - t1
其他回答
Python的魔力内置类型
在python中,仅通过python的内置类型就可以很容易地处理这样复杂的情况。
让我告诉你怎么做!
方法一:一般情况
方法(1行代码)删除重复的元素在列表中仍然保持排序顺序
line = [1, 2, 3, 1, 2, 5, 6, 7, 8]
new_line = sorted(set(line), key=line.index) # remove duplicated element
print(new_line)
你会得到结果的
[1, 2, 3, 5, 6, 7, 8]
方法二:特殊情况
TypeError: unhashable type: 'list'
处理不可哈希的特殊情况(3行代码)
line=[['16.4966155686595', '-27.59776154691', '52.3786295521147']
,['16.4966155686595', '-27.59776154691', '52.3786295521147']
,['17.6508629295574', '-27.143305738671', '47.534955022564']
,['17.6508629295574', '-27.143305738671', '47.534955022564']
,['18.8051102904552', '-26.688849930432', '42.6912804930134']
,['18.8051102904552', '-26.688849930432', '42.6912804930134']
,['19.5504702331098', '-26.205884452727', '37.7709192714727']
,['19.5504702331098', '-26.205884452727', '37.7709192714727']
,['20.2929416861422', '-25.722717575124', '32.8500163147157']
,['20.2929416861422', '-25.722717575124', '32.8500163147157']]
tuple_line = [tuple(pt) for pt in line] # convert list of list into list of tuple
tuple_new_line = sorted(set(tuple_line),key=tuple_line.index) # remove duplicated element
new_line = [list(t) for t in tuple_new_line] # convert list of tuple into list of list
print (new_line)
你会得到这样的结果:
[
['16.4966155686595', '-27.59776154691', '52.3786295521147'],
['17.6508629295574', '-27.143305738671', '47.534955022564'],
['18.8051102904552', '-26.688849930432', '42.6912804930134'],
['19.5504702331098', '-26.205884452727', '37.7709192714727'],
['20.2929416861422', '-25.722717575124', '32.8500163147157']
]
因为元组是可哈希的,你可以很容易地在列表和元组之间转换数据
def remove_duplicates(input_list):
if input_list == []:
return []
#sort list from smallest to largest
input_list=sorted(input_list)
#initialize ouput list with first element of the sorted input list
output_list = [input_list[0]]
for item in input_list:
if item >output_list[-1]:
output_list.append(item)
return output_list
简单易行:
myList = [1, 2, 3, 1, 2, 5, 6, 7, 8]
cleanlist = []
[cleanlist.append(x) for x in myList if x not in cleanlist]
输出:
>>> cleanlist
[1, 2, 3, 5, 6, 7, 8]
也有使用Pandas和Numpy的解决方案。它们都返回numpy数组,所以如果你想要一个列表,你必须使用.tolist()函数。
t=['a','a','b','b','b','c','c','c']
t2= ['c','c','b','b','b','a','a','a']
熊猫的解决方案
唯一使用Pandas函数():
import pandas as pd
pd.unique(t).tolist()
>>>['a','b','c']
pd.unique(t2).tolist()
>>>['c','b','a']
Numpy解决方案
使用numpy函数unique()。
import numpy as np
np.unique(t).tolist()
>>>['a','b','c']
np.unique(t2).tolist()
>>>['a','b','c']
注意,numpy.unique()也对值进行排序。所以列表t2是有序返回的。如果你想保留顺序,可以这样回答:
_, idx = np.unique(t2, return_index=True)
t2[np.sort(idx)].tolist()
>>>['c','b','a']
与其他解决方案相比,该解决方案并不那么优雅,但是,与pandas.unique()相比,numpy.unique()还允许您检查嵌套数组在选定的轴上是否唯一。
到目前为止,我看到的所有保持顺序的方法要么使用朴素比较(时间复杂度最多为O(n^2)),要么使用限制于可哈希输入的重载OrderedDicts/set+list组合。下面是一个与哈希无关的O(nlogn)解决方案:
更新增加了关键参数、文档和Python 3兼容性。
# from functools import reduce <-- add this import on Python 3
def uniq(iterable, key=lambda x: x):
"""
Remove duplicates from an iterable. Preserves order.
:type iterable: Iterable[Ord => A]
:param iterable: an iterable of objects of any orderable type
:type key: Callable[A] -> (Ord => B)
:param key: optional argument; by default an item (A) is discarded
if another item (B), such that A == B, has already been encountered and taken.
If you provide a key, this condition changes to key(A) == key(B); the callable
must return orderable objects.
"""
# Enumerate the list to restore order lately; reduce the sorted list; restore order
def append_unique(acc, item):
return acc if key(acc[-1][1]) == key(item[1]) else acc.append(item) or acc
srt_enum = sorted(enumerate(iterable), key=lambda item: key(item[1]))
return [item[1] for item in sorted(reduce(append_unique, srt_enum, [srt_enum[0]]))]