목록에서 중복 제거
목록에 중복 항목이 있는지 확인하고 중복 항목이 있는지 확인하는 프로그램을 작성해야하며 중복 / 제거되지 않은 항목이있는 새 목록을 반환합니다. 이것은 내가 가진 것이지만 솔직히 무엇을 해야할지 모르겠습니다.
def remove_duplicates():
t = ['a', 'b', 'c', 'd']
t2 = ['a', 'c', 'd']
for t in t2:
t.append(t.remove())
return t
고유 한 항목 컬렉션을 가져 오는 일반적인 방법은 set
. 집합은 고유 한 개체 의 정렬되지 않은 컬렉션입니다 . 이터 러블에서 집합을 만들려면 간단히 내장 함수에 전달하면됩니다 . 나중에 실제 목록이 다시 필요하면 유사하게 집합을 함수에 전달할 수 있습니다 .set()
list()
다음 예제는 수행하려는 모든 작업을 다루어야합니다.
>>> t = [1, 2, 3, 1, 2, 5, 6, 7, 8]
>>> t
[1, 2, 3, 1, 2, 5, 6, 7, 8]
>>> list(set(t))
[1, 2, 3, 5, 6, 7, 8]
>>> s = [1, 2, 3]
>>> list(set(t) - set(s))
[8, 5, 6, 7]
예제 결과에서 알 수 있듯이 원래 주문은 유지되지 않습니다 . 위에서 언급했듯이 세트 자체는 순서가 지정되지 않은 컬렉션이므로 순서가 손실됩니다. 세트를 다시 목록으로 변환 할 때 임의의 순서가 생성됩니다.
질서 유지
순서가 중요하다면 다른 메커니즘을 사용해야합니다. 이에 대한 매우 일반적인 해결책은 OrderedDict
삽입하는 동안 키의 순서를 유지하는 것입니다.
>>> from collections import OrderedDict
>>> list(OrderedDict.fromkeys(t))
[1, 2, 3, 5, 6, 7, 8]
Python 3.7부터 내장 사전도 삽입 순서를 유지하도록 보장되므로 Python 3.7 이상 (또는 CPython 3.6)을 사용하는 경우 직접 사용할 수도 있습니다.
>>> list(dict.fromkeys(t))
[1, 2, 3, 5, 6, 7, 8]
이것은 먼저 사전을 만든 다음 그로부터 목록을 만드는 오버 헤드가 있습니다. 실제로 주문을 유지할 필요가 없다면 세트를 사용하는 것이 좋습니다. 중복 항목을 제거 할 때 순서를 유지하는 자세한 내용과 대체 방법은 이 질문 을 확인하세요 .
마지막으로 / 솔루션 set
과 함께 모두 항목이 해시 가능 해야합니다 . 이것은 일반적으로 변경 불가능해야 함을 의미합니다. 해시 할 수없는 항목 (예 : 목록 개체)을 처리해야하는 경우 기본적으로 모든 항목을 중첩 된 루프의 다른 모든 항목과 비교해야하는 느린 접근 방식을 사용해야합니다.OrderedDict
dict
Python 2.7 에서 원래 순서대로 유지하면서 iterable에서 중복 항목을 제거하는 새로운 방법은 다음과 같습니다.
>>> from collections import OrderedDict
>>> list(OrderedDict.fromkeys('abracadabra'))
['a', 'b', 'r', 'c', 'd']
Python 3.5 에서 OrderedDict에는 C 구현이 있습니다. 내 타이밍은 이것이 이제 Python 3.5에 대한 다양한 접근 방식 중 가장 빠르고 가장 짧다는 것을 보여줍니다.
Python 3.6 에서 일반 dict는 순서가 지정되고 압축되었습니다. (이 기능은 CPython 및 PyPy에 적용되지만 다른 구현에서는 제공되지 않을 수 있습니다.) 이는 순서를 유지하면서 새로운 가장 빠른 중복 제거 방법을 제공합니다.
>>> list(dict.fromkeys('abracadabra'))
['a', 'b', 'r', 'c', 'd']
Python 3.7 에서 일반 dict는 모든 구현에서 모두 정렬됩니다. 따라서 가장 짧고 빠른 솔루션은 다음과 같습니다.
>>> list(dict.fromkeys('abracadabra'))
['a', 'b', 'r', 'c', 'd']
한 줄짜리 : list(set(source_list))
트릭을 수행합니다.
A set
는 중복 될 수없는 것입니다.
업데이트 : 주문 보존 방식은 두 줄입니다.
from collections import OrderedDict
OrderedDict((x, True) for x in source_list).keys()
여기서 우리 OrderedDict
는 키의 삽입 순서 를 기억하고 특정 키의 값이 업데이트 될 때 변경하지 않는 사실을 사용합니다 . True
값으로 삽입 하지만 어떤 것도 삽입 할 수 있으며 값은 사용되지 않습니다. ( 무시 된 값을 사용 set
하는 a dict
와 비슷하게 작동합니다 .)
>>> t = [1, 2, 3, 1, 2, 5, 6, 7, 8]
>>> t
[1, 2, 3, 1, 2, 5, 6, 7, 8]
>>> s = []
>>> for i in t:
if i not in s:
s.append(i)
>>> s
[1, 2, 3, 5, 6, 7, 8]
주문이 마음에 들지 않으면 다음과 같이하십시오.
def remove_duplicates(l):
return list(set(l))
A set
는 중복되지 않음을 보장합니다.
중복의 첫 번째 요소 순서를 유지하는 새 목록을 만들려면 L
newlist=[ii for n,ii in enumerate(L) if ii not in L[:n]]
예를 들어 if L=[1, 2, 2, 3, 4, 2, 4, 3, 5]
다음 newlist
은[1,2,3,4,5]
이렇게하면 각 새 요소를 추가하기 전에 목록에 이전에 나타나지 않았는지 확인합니다. 또한 수입이 필요하지 않습니다.
동료가 오늘 코드 검토를 위해 코드의 일부로 수락 된 답변을 나에게 보냈습니다. 질문에 대한 대답의 우아함은 확실히 존경하지만 성능에 만족하지 않습니다. 이 솔루션을 시도했습니다 ( 조회 시간을 줄이기 위해 set 을 사용 합니다 )
def ordered_set(in_list):
out_list = []
added = set()
for val in in_list:
if not val in added:
out_list.append(val)
added.add(val)
return out_list
효율성을 비교하기 위해 100 개의 정수로 구성된 무작위 샘플을 사용했습니다. 62 개는 고유했습니다.
from random import randint
x = [randint(0,100) for _ in xrange(100)]
In [131]: len(set(x))
Out[131]: 62
측정 결과는 다음과 같습니다.
In [129]: %timeit list(OrderedDict.fromkeys(x))
10000 loops, best of 3: 86.4 us per loop
In [130]: %timeit ordered_set(x)
100000 loops, best of 3: 15.1 us per loop
음, 세트가 솔루션에서 제거되면 어떻게됩니까?
def ordered_set(inlist):
out_list = []
for val in inlist:
if not val in out_list:
out_list.append(val)
return out_list
결과는 OrderedDict 만큼 나쁘지는 않지만 여전히 원래 솔루션의 3 배 이상입니다.
In [136]: %timeit ordered_set(x)
10000 loops, best of 3: 52.6 us per loop
다른 방법 :
>>> seq = [1,2,3,'a', 'a', 1,2]
>> dict.fromkeys(seq).keys()
['a', 1, 2, 3]
Pandas와 Numpy를 사용하는 솔루션도 있습니다. 둘 다 numpy 배열을 반환하므로 .tolist()
목록을 원하면 함수를 사용해야 합니다.
t=['a','a','b','b','b','c','c','c']
t2= ['c','c','b','b','b','a','a','a']
판다 솔루션
Pandas 기능 사용 unique()
:
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 ()를 사용하면 중첩 배열이 선택한 축을 따라 고유한지 확인할 수도 있습니다.
간단하고 쉬움 :
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]
내 목록에 사전이 있으므로 위의 접근 방식을 사용할 수 없습니다. 오류가 발생했습니다.
TypeError: unhashable type:
따라서 주문 및 / 또는 일부 항목에 관심 이 있다면 해시 할 수 없습니다 . 그러면 다음이 유용 할 수 있습니다.
def make_unique(original_list):
unique_list = []
[unique_list.append(obj) for obj in original_list if obj not in unique_list]
return unique_list
어떤 사람들은 부작용이있는 목록 이해가 좋은 해결책이 아니라고 생각할 수 있습니다. 다음은 대안입니다.
def make_unique(original_list):
unique_list = []
map(lambda x: unique_list.append(x) if (x not in unique_list) else False, original_list)
return unique_list
지금까지 내가 본 모든 순서 보존 접근 방식은 순진한 비교 (기껏해야 O (n ^ 2) 시간 복잡도 포함) 또는 해시 가능한 입력으로 제한되는 무거운 OrderedDicts
/ set
+ list
조합을 사용합니다. 다음은 해시 독립적 인 O (nlogn) 솔루션입니다.
업데이트 는 key
인수, 문서 및 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]]))]
세트를 사용해보십시오.
import sets
t = sets.Set(['a', 'b', 'c', 'd'])
t1 = sets.Set(['a', 'b', 'c'])
print t | t1
print t - t1
다음과 같이 할 수도 있습니다.
>>> t = [1, 2, 3, 3, 2, 4, 5, 6]
>>> s = [x for i, x in enumerate(t) if i == t.index(x)]
>>> s
[1, 2, 3, 4, 5, 6]
위의 작동 이유는 index
메서드가 요소의 첫 번째 인덱스 만 반환하기 때문입니다 . 중복 요소는 인덱스가 더 높습니다. 여기를 참조 하십시오 :
list.index (x [, start [, end]])
값이 x 인 첫 번째 항목의 목록에서 0 부터 시작 하는 인덱스를 반환합니다. 해당 항목이 없으면 ValueError를 발생시킵니다.
주문 보존으로 변형 감소 :
목록이 있다고 가정합니다.
l = [5, 6, 6, 1, 1, 2, 2, 3, 4]
변형 감소 (비효율적) :
>>> reduce(lambda r, v: v in r and r or r + [v], l, [])
[5, 6, 1, 2, 3, 4]
5 배 더 빠르지 만 더 정교함
>>> reduce(lambda r, v: v in r[1] and r or (r[0].append(v) or r[1].add(v)) or r, l, ([], set()))[0]
[5, 6, 1, 2, 3, 4]
설명:
default = (list(), set())
# user list to keep order
# use set to make lookup faster
def reducer(result, item):
if item not in result[1]:
result[0].append(item)
result[1].add(item)
return result
reduce(reducer, l, default)[0]
목록에서 중복을 제거하는 가장 좋은 방법은 파이썬에서 사용할 수있는 set () 함수를 사용하여 해당 집합을 다시 목록으로 변환하는 것 입니다.
In [2]: some_list = ['a','a','v','v','v','c','c','d']
In [3]: list(set(some_list))
Out[3]: ['a', 'c', 'd', 'v']
다음 기능을 사용할 수 있습니다.
def rem_dupes(dup_list):
yooneeks = []
for elem in dup_list:
if elem not in yooneeks:
yooneeks.append(elem)
return yooneeks
예 :
my_list = ['this','is','a','list','with','dupicates','in', 'the', 'list']
용법:
rem_dupes(my_list)
[ 'this', 'is', 'a', 'list', 'with', 'dupicates', 'in', 'the']
순서를 유지하고 외부 모듈을 사용하지 않으려면 여기에서 쉽게 수행 할 수 있습니다.
>>> t = [1, 9, 2, 3, 4, 5, 3, 6, 7, 5, 8, 9]
>>> list(dict.fromkeys(t))
[1, 9, 2, 3, 4, 5, 6, 7, 8]
참고 :이 방법은 표시 순서를 유지하므로 위에서 볼 수 있듯이 처음 등장했기 때문에 9 개가 1 개 뒤에 나옵니다. 그러나 이것은 당신이 할 때 얻을 수있는 것과 같은 결과입니다.
from collections import OrderedDict
ulist=list(OrderedDict.fromkeys(l))
그러나 훨씬 더 짧고 더 빠르게 실행됩니다.
This works because each time the fromkeys
function tries to create a new key, if the value already exists it will simply overwrite it. This wont affect the dictionary at all however, as fromkeys
creates a dictionary where all keys have the value None
, so effectively it eliminates all duplicates this way.
There are many other answers suggesting different ways to do this, but they're all batch operations, and some of them throw away the original order. That might be okay depending on what you need, but if you want to iterate over the values in the order of the first instance of each value, and you want to remove the duplicates on-the-fly versus all at once, you could use this generator:
def uniqify(iterable):
seen = set()
for item in iterable:
if item not in seen:
seen.add(item)
yield item
This returns a generator/iterator, so you can use it anywhere that you can use an iterator.
for unique_item in uniqify([1, 2, 3, 4, 3, 2, 4, 5, 6, 7, 6, 8, 8]):
print(unique_item, end=' ')
print()
Output:
1 2 3 4 5 6 7 8
If you do want a list
, you can do this:
unique_list = list(uniqify([1, 2, 3, 4, 3, 2, 4, 5, 6, 7, 6, 8, 8]))
print(unique_list)
Output:
[1, 2, 3, 4, 5, 6, 7, 8]
Without using set
data=[1, 2, 3, 1, 2, 5, 6, 7, 8]
uni_data=[]
for dat in data:
if dat not in uni_data:
uni_data.append(dat)
print(uni_data)
This one cares about the order without too much hassle (OrderdDict & others). Probably not the most Pythonic way, nor shortest way, but does the trick:
def remove_duplicates(list):
''' Removes duplicate items from a list '''
singles_list = []
for element in list:
if element not in singles_list:
singles_list.append(element)
return singles_list
below code is simple for removing duplicate in list
def remove_duplicates(x):
a = []
for i in x:
if i not in a:
a.append(i)
return a
print remove_duplicates([1,2,2,3,3,4])
it returns [1,2,3,4]
Using set :
a = [0,1,2,3,4,3,3,4]
a = list(set(a))
print a
Using unique :
import numpy as np
a = [0,1,2,3,4,3,3,4]
a = np.unique(a).tolist()
print a
One more better approach could be,
import pandas as pd
myList = [1, 2, 3, 1, 2, 5, 6, 7, 8]
cleanList = pd.Series(myList).drop_duplicates().tolist()
print(cleanList)
#> [1, 2, 3, 5, 6, 7, 8]
and the order remains preserved.
Here's the fastest pythonic solution comaring to others listed in replies.
Using implementation details of short-circuit evaluation allows to use list comprehension, which is fast enough. visited.add(item)
always returns None
as a result, which is evaluated as False
, so the right-side of or
would always be the result of such an expression.
Time it yourself
def deduplicate(sequence):
visited = set()
adder = visited.add # get rid of qualification overhead
out = [adder(item) or item for item in sequence if item not in visited]
return out
Very simple way in Python 3:
>>> n = [1, 2, 3, 4, 1, 1]
>>> n
[1, 2, 3, 4, 1, 1]
>>> m = sorted(list(set(n)))
>>> m
[1, 2, 3, 4]
You can use set
to remove duplicates:
mylist = list(set(mylist))
But note the results will be unordered. If that's an issue:
mylist.sort()
Here is an example, returning list without repetiotions preserving order. Does not need any external imports.
def GetListWithoutRepetitions(loInput):
# return list, consisting of elements of list/tuple loInput, without repetitions.
# Example: GetListWithoutRepetitions([None,None,1,1,2,2,3,3,3])
# Returns: [None, 1, 2, 3]
if loInput==[]:
return []
loOutput = []
if loInput[0] is None:
oGroupElement=1
else: # loInput[0]<>None
oGroupElement=None
for oElement in loInput:
if oElement<>oGroupElement:
loOutput.append(oElement)
oGroupElement = oElement
return loOutput
Check this if you want to remove duplicates (in-place edit rather than returning new list) without using inbuilt set, dict.keys, uniqify, counter
>>> t = [1, 2, 3, 1, 2, 5, 6, 7, 8]
>>> for i in t:
... if i in t[t.index(i)+1:]:
... t.remove(i)
...
>>> t
[3, 1, 2, 5, 6, 7, 8]
I think converting to set is the easiest way to remove duplicate:
list1 = [1,2,1]
list1 = list(set(list1))
print list1
참고URL : https://stackoverflow.com/questions/7961363/removing-duplicates-in-lists
'your programing' 카테고리의 다른 글
Git 병합 마스터를 기능 브랜치로 (0) | 2020.09.28 |
---|---|
부트 스트랩 3과 수직 정렬 (0) | 2020.09.28 |
std :: string을 const char * 또는 char *로 변환하는 방법은 무엇입니까? (0) | 2020.09.28 |
SQL Server에서 작은 따옴표를 어떻게 이스케이프합니까? (0) | 2020.09.28 |
Git에서 이전 커밋에 태그를 지정하는 방법은 무엇입니까? (0) | 2020.09.28 |