주문을 유지하면서 목록에서 중복 항목을 제거하려면 어떻게 해야 합니까?
주문을 유지하면서 목록에서 중복 항목을 제거하려면 어떻게 해야 합니까?세트를 사용하여 중복을 제거하면 원래 주문이 삭제됩니다.붙박이 사자성어나 피토닉 사자성어가 있나요?
관련 질문:Python에서 순서를 유지하면서 모든 요소가 고유하도록 목록에서 중복을 제거하는 가장 빠른 알고리즘은 무엇입니까?
여기 몇 가지 대안이 있습니다.http://www.peterbe.com/plog/uniqifiers-benchmark
가장 빠른 것:
def f7(seq):
seen = set()
seen_add = seen.add
return [x for x in seq if not (x in seen or seen_add(x))]
「」를 할당하는 seen.add
로로 합니다.seen_add
'만'이라고 부르는 것이 '만'이라고 부르면 안 돼요.seen.add
이며, Python입니다seen.add
각 반복은 로컬 변수를 해결하는 것보다 비용이 많이 듭니다. seen.add
반복 간에 변경될 수 있으며 실행 시간이 충분히 스마트하지 않아 이를 배제할 수 없습니다.안전하게 플레이하려면 매번 물체를 확인해야 합니다.
같은 데이터 세트에서 이 기능을 많이 사용할 계획이라면 http://code.activestate.com/recipes/528878/를 주문하는 것이 좋습니다.
작업별 O(1) 삽입, 삭제 및 멤버 체크.
추가 메모: (소량 추가 메모seen.add()
반환하다None
따라서 위의 내용은 세트업데이트를 시행하는 방법으로서만 사용할 수 있으며 논리 테스트의 일부로서는 사용할 수 없습니다).
최적의 솔루션은 Python 버전 및 환경 제약에 따라 달라집니다.
Python 3.7+(및 구현 세부사항으로 3.6을 지원하는 대부분의 인터프리터):
.53.후.Python 2.5.0에서 Python 3.7에서 언어 보증이 이루어졌습니다.dict
는 삽입 ( 3)보다 입니다.collections.OrderedDict
따라서 가장 빠른 솔루션은 가장 간단한 솔루션이기도 합니다.
>>> items = [1, 2, 0, 1, 3, 2]
>>> list(dict.fromkeys(items)) # Or [*dict.fromkeys(items)] if you prefer
[1, 2, 0, 3]
맘에 들다list(set(items))
에 의해, 모든 이 C 상)에 푸시 만, 「C」(CPython)이기 때문에,dict
삽입순서입니다.dict.fromkeys
순서를 잃지 않습니다.list(set(items))
(일반적으로 50~100% 더 오래 걸리지만) 다른 주문 유지 솔루션보다 훨씬 빠릅니다(리스트콤에서 를 사용하는 해킹 시간의 약 절반).
중요사항:그unique_everseen
결 from의 more_itertools
(아래 참조)는 게으름과 비사용 입력 항목에 대한 지원이라는 점에서 몇 가지 고유한 이점이 있습니다. 이러한 기능이 필요한 경우 이 솔루션만이 유효합니다.
Python 3.5(및 성능이 중요하지 않은 경우 모든 이전 버전)
Raymond가 지적했듯이 CPython 3.5에서는OrderedDict
의 이해 C보다 .추측 리스트의 이해 해크는, 보다 느립니다.OrderedDict.fromkeys
(마지막에 실제로 목록이 필요한 경우를 제외하고 입력이 매우 짧은 경우에만 해당).3.에 가장 은 CPython 3.5입니다.OrderedDict
의 3.에 하는 양dict
:
>>> from collections import OrderedDict
>>> items = [1, 2, 0, 1, 3, 2]
>>> list(OrderedDict.fromkeys(items))
[1, 2, 0, 3]
CPython 3.4 이전 버전에서는 다른 솔루션보다 속도가 느리므로 프로파일링에서 더 나은 솔루션이 필요한 경우 계속 읽어보십시오.
Python 3.4 이전 버전(성능이 중요하고 타사 모듈을 사용할 수 있는 경우)
@abarnert가 말했듯이 라이브러리(pip install more_itertools
에는, 이 문제를 판독할 수 없는 일 없이 해결할 수 있는 기능이 포함되어 있습니다( ).not seen.add
)의 리스트 컴프리션의 돌연변이.이것이 가장 빠른 해결책이기도 합니다.
>>> from more_itertools import unique_everseen
>>> items = [1, 2, 0, 1, 3, 2]
>>> list(unique_everseen(items))
[1, 2, 0, 3]
간단한 라이브러리 Import만 하면 해킹은 없습니다.
모듈은 다음과 같은 반복 도구 레시피를 적용하고 있습니다.
def unique_everseen(iterable, key=None):
"List unique elements, preserving order. Remember all elements ever seen."
# unique_everseen('AAAABBBCCDAABBB') --> A B C D
# unique_everseen('ABBCcAD', str.lower) --> A B C D
seen = set()
seen_add = seen.add
if key is None:
for element in filterfalse(seen.__contains__, iterable):
seen_add(element)
yield element
else:
for element in iterable:
k = key(element)
if k not in seen:
seen_add(k)
yield element
but하 the the the the the the the와는 itertools
에서는, 「코스트」에 포함되는 의 경우는, 「Recipe」를 서포트하고 .iterable
은 해석할 수 은 '알고리즘」이 됩니다.O(n²)
. , . . . . . . . . . . .O(n)
」를 참조해 주세요.
중요사항:여기 있는 다른 모든 솔루션과 달리unique_everseen
느긋하게 할 수 사용량이 같아집니다).최대 메모리 사용량이 같아집니다(결국 기반이 되는 메모리 사용량이 같아집니다).set
). 하지만 그렇지 않으면list
결과를 반복하기만 하면 첫 번째 고유 항목을 처리하기 전에 입력 전체가 중복 제거될 때까지 기다리지 않고 발견된 고유 항목을 즉시 처리할 수 있습니다.
Python 3.4 이전 버전, 성능이 중요하고 타사 모듈을 사용할 수 없는 경우
두 가지 옵션이 있습니다.
레시피를 코드에 복사하여 붙여넣기하여
more_itertools
의 예가 listcomp를 및할 수 합니다.
set
것을하다: 본 것을 추적하다.seen = set() [x for x in seq if x not in seen and not seen.add(x)]
그 추악한 해킹에 의존하면서 말이죠.
not seen.add(x)
합니다.
set.add
in-place로 입니다.None
not None
True
.
위의 모든 솔루션은 다음과 같습니다.O(n)
calling(콜 저장))unique_everseen
할 수 , 즉, 「반복할 수 없는 아이템에 대해서」, 「반복할 수 없는 아이템 「」O(n²)
다른 것들은 즉시 실패한다.TypeError
있을 때가 아닌 코드 경로)아서, 모든 해결책 충분히 성능 기준에 맞는 있다.어떤 사용할 언어를 당신은 spec/interpreter/third-party 모듈 의존할 수 있는 버전에 만약 나중에 이 코드를 유지하고 있는 사람이 살인적인 분위기에 끝나겠지, 이어지든 말든 성능은 중요한( 그렇다 하고 그것은 보통지 않는다고 가정하지 않아), 그리고 가장 중요한 것은 가독성(, 왜냐하면 당신의 영리한 micro-optimization 아마도 w. 달려 있로)의 가치도 없다.
CPython 3.6+(그리고 모든 다른 파이썬 구현 파이선 3.7+부터 시작하여)에서, 사전, 그래서 길이 원본 순서에 맞는 것이다하면iterable에서 중복을 제거하도록 강제된다.
>>> list(dict.fromkeys('abracadabra'))
['a', 'b', 'r', 'c', 'd']
파이선 3.5(파이선 2.7포함)고 아래에서, OrderedDict를 사용한다.내 타이밍은 이 지금 둘 다, Python3.5( 때;C구현했다 앞서 3.5미터에서 아직도 그 비젼에는 해결책 아니지만 가장 빠른)에 대한 다양한 접근법의 짧은 빠른 것을 보여 준다.
>>> from collections import OrderedDict
>>> list(OrderedDict.fromkeys('abracadabra'))
['a', 'b', 'r', 'c', 'd']
지만 여기 해결책은 꽤 빨리 많은 상황에서 죽어 사용하기가 간단하다는 것이다 pandas를 사용하고 있다 죽은 말( 좋은 답이 이 질문은 매우 벌써 오래 된 많은)을 차기도 한다.
import pandas as pd
my_list = [0, 1, 2, 3, 4, 1, 2, 3, 5]
>>> pd.Series(my_list).drop_duplicates().tolist()
# Output:
# [0, 1, 2, 3, 4, 5]
파이선 3.7, 위에서, 사전은 기본 삽입 위해 기억하는 것을 보장 받는다.이 질문에 대한 대답은 시국을 요약하였다.
OrderedDict
해결책이 되어 어떤 수입 발언 없이 우리는 단순히 발행할 수 있습니다:구식이 된다.
>>> lst = [1, 2, 1, 3, 3, 2, 4]
>>> list(dict.fromkeys(lst))
[1, 2, 3, 4]
sequence = ['1', '2', '3', '3', '6', '4', '5', '6']
unique = []
[unique.append(item) for item in sequence if item not in unique]
→ 고유 →['1', '2', '3', '6', '4', '5']
from itertools import groupby
[ key for key,_ in groupby(sortedList)]
그 리스트는 정렬될, 필요 충분 조건은 평등 가치 함께 그룹화됩니다 필요가 없는다.
편집:나는"주문을 보존하기"은 리스트는 명령이다는 것을 암시하고 있었다.만약 이 있지 않다면, 그때는 MizardX에서 해결 방안은 맞네요.
지역 사회 편집:이것은 하지만 가장 우아한 방법"압축 파일을 단일 요소에 연속 요소 중복".
질서를 유지하고 싶다면
다음과 같이 시험해 볼 수 있습니다.
list1 = ['b','c','d','b','c','a','a']
list2 = list(set(list1))
list2.sort(key=list1.index)
print list2
또는 다음과 같이 할 수 있습니다.
list1 = ['b','c','d','b','c','a','a']
list2 = sorted(set(list1),key=list1.index)
print list2
다음 작업도 수행할 수 있습니다.
list1 = ['b','c','d','b','c','a','a']
list2 = []
for i in list1:
if not i in list2:
list2.append(i)`
print list2
다음과 같이 쓸 수도 있습니다.
list1 = ['b','c','d','b','c','a','a']
list2 = []
[list2.append(i) for i in list1 if not i in list2]
print list2
외부1 모듈로부터 이러한 기능의 다른(매우 퍼포먼스) 실장을 추가하는 것만으로, 다음과 같습니다.
>>> from iteration_utilities import unique_everseen
>>> lst = [1,1,1,2,3,2,2,2,1,3,4]
>>> list(unique_everseen(lst))
[1, 2, 3, 4]
타이밍
가지 3.6. 3.6, 피톤 3.6 등입니다.OrderedDict.fromkeys
,f7
★★★★★★★★★★★★★★★★★」more_itertools.unique_everseen
:
%matplotlib notebook
from iteration_utilities import unique_everseen
from collections import OrderedDict
from more_itertools import unique_everseen as mi_unique_everseen
def f7(seq):
seen = set()
seen_add = seen.add
return [x for x in seq if not (x in seen or seen_add(x))]
def iteration_utilities_unique_everseen(seq):
return list(unique_everseen(seq))
def more_itertools_unique_everseen(seq):
return list(mi_unique_everseen(seq))
def odict(seq):
return list(OrderedDict.fromkeys(seq))
from simple_benchmark import benchmark
b = benchmark([f7, iteration_utilities_unique_everseen, more_itertools_unique_everseen, odict],
{2**i: list(range(2**i)) for i in range(1, 20)},
'list size (no duplicates)')
b.plot()
또한 더 많은 중복을 사용하여 테스트도 실시하여 차이가 있는지 확인합니다.
import random
b = benchmark([f7, iteration_utilities_unique_everseen, more_itertools_unique_everseen, odict],
{2**i: [random.randint(0, 2**(i-1)) for _ in range(2**i)] for i in range(1, 20)},
'list size (lots of duplicates)')
b.plot()
또한 하나의 값만 포함하는 값:
b = benchmark([f7, iteration_utilities_unique_everseen, more_itertools_unique_everseen, odict],
{2**i: [1]*(2**i) for i in range(1, 20)},
'list size (only duplicates)')
b.plot()
, 「」는iteration_utilities.unique_everseen
이데올로기 때문에
★★★★★★★★★★★★★★★★★.iteration_utilities.unique_everseen
을 처리할 도 있습니다(, 「」는 「」로 설정되어 있습니다).O(n*n)
(Performance)가 아닌O(n)
퍼포먼스를 향상시킵니다).
>>> lst = [{1}, {1}, {2}, {1}, {3}]
>>> list(unique_everseen(lst))
[{1}, {2}, {3}]
1 면책사항:저는 그 패키지의 작성자입니다.
또 다른 매우 오래된 질문에 대한 매우 늦은 답변:
레시피에는 이 기능을 하는 기능이 있습니다.seen
technology, 설정 방법:
- 합니다.
key
★★★★★★ 。 - 꼴사나운 해커를 쓰지 않는다.
- 합니다.
seen.add
f7
이 동작도 합니다만, 일부의 버전에서는 동작하지 않습니다). - 하여 루프를 합니다.
ifilterfalse
Python의 Python의 한 요소 Python의 모든 에 대해 됩니다.)ifilterfalse
물론입니다만, 이것은 C단위로, 훨씬 더 빠릅니다.)
실제로 이 속도보다 빠릅니까?f7
데이터에 따라 다르므로 테스트하고 확인해야 합니다.는, 「」를 참조해 주세요.f7
는 listcomp를 (직접 listcomp를 할 수 .)append
yield
또는를 ing으로 수 .list
listcomp하다 LIST_APPEND입니다.어쨌든 보통 몇 마이크로초를 짜내는 것은 쉽게 이해할 수 있고 재사용 가능하며 이미 작성된 기능을 사용하는 것만큼 중요하지 않습니다. 이 기능은 꾸미고 싶을 때 DSU를 필요로 하지 않습니다.
모든 레시피와 마찬가지로 에서도 사용할 수 있습니다.
이 no-no-no-no-no-no-no-no-no-no-no-nkey
을 사용하다
def unique(iterable):
seen = set()
seen_add = seen.add
for element in itertools.ifilterfalse(seen.__contains__, iterable):
seen_add(element)
yield element
MizardX에 따라 해시 가능한 유형(예: 목록)이 없는 경우:
def f7_noHash(seq)
seen = set()
return [ x for x in seq if str( x ) not in seen and not seen.add( str( x ) )]
5배 빠른 속도, 변종 감소 및 고급화
>>> l = [5, 6, 6, 1, 1, 2, 2, 3, 4]
>>> 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())
# use 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]
[5, 6, 1, 2, 3, 4]
간단한 방법은 다음과 같습니다.
list1 = ["hello", " ", "w", "o", "r", "l", "d"]
sorted(set(list1 ), key=list1.index)
다음과 같은 출력을 나타냅니다.
["hello", " ", "w", "o", "r", "l", "d"]
팬더 사용자들은 확인해야 한다.
>>> import pandas as pd
>>> lst = [1, 2, 1, 3, 3, 2, 4]
>>> pd.unique(lst)
array([1, 2, 3, 4])
함수는 NumPy 어레이를 반환합니다.필요한 경우 메서드를 사용하여 목록으로 변환할 수 있습니다.
의 Haskell을하는 데 nub
목록에 대한 함수, 이것은 재귀적 접근법입니다.
def unique(lst):
return [] if lst==[] else [lst[0]] + unique(filter(lambda x: x!= lst[0], lst[1:]))
예:
In [118]: unique([1,5,1,1,4,3,4])
Out[118]: [1, 5, 4, 3]
데이터 크기를 늘리기 위해 시도해보니 선형 이하의 시간 복잡성이 확인되었습니다(확정적이지는 않지만 일반 데이터라면 충분하다는 것을 시사함).
In [122]: %timeit unique(np.random.randint(5, size=(1)))
10000 loops, best of 3: 25.3 us per loop
In [123]: %timeit unique(np.random.randint(5, size=(10)))
10000 loops, best of 3: 42.9 us per loop
In [124]: %timeit unique(np.random.randint(5, size=(100)))
10000 loops, best of 3: 132 us per loop
In [125]: %timeit unique(np.random.randint(5, size=(1000)))
1000 loops, best of 3: 1.05 ms per loop
In [126]: %timeit unique(np.random.randint(5, size=(10000)))
100 loops, best of 3: 11 ms per loop
또, 다른 업무에 의해서도, 개성이 용이하게 일반화할 수 있는 것도 흥미롭다고 생각합니다.다음과 같이 합니다.
import operator
def unique(lst, cmp_op=operator.ne):
return [] if lst==[] else [lst[0]] + unique(filter(lambda x: cmp_op(x, lst[0]), lst[1:]), cmp_op)
예를 들어 고유성을 위해 동일한 정수로 반올림하는 개념을 사용하는 함수를 다음과 같이 전달할 수 있습니다.
def test_round(x,y):
return round(x) != round(y)
그러면 unique(some_list, test_round)는 목록의 고유한 요소를 제공합니다. 여기서 유니크성은 더 이상 전통적인 평등을 의미하지 않고(이 문제에 대한 모든 종류의 세트 기반 또는 딕트 키 기반 접근방식을 사용함으로써 암시됨), 대신 요소가 발생할 수 있는 각 정수 K에 대해 K로 반올림되는 첫 번째 요소만 취하도록 의도됩니다.d to. 예:
In [6]: unique([1.2, 5, 1.9, 1.1, 4.2, 3, 4.8], test_round)
Out[6]: [1.2, 5, 1.9, 4.2, 3]
목록 이해는 기호 '_[1]'로 작성되므로 참조할 수 있습니다.
예를 들어, 다음 함수는 목록 이해를 참조하여 요소의 순서를 변경하지 않고 요소의 목록을 고유하게 표시합니다.
def unique(my_list):
return [x for x in my_list if x not in locals()['_[1]']]
데모:
l1 = [1, 2, 3, 4, 1, 2, 3, 4, 5]
l2 = [x for x in l1 if x not in locals()['_[1]']]
print l2
출력:
[1, 2, 3, 4, 5]
이 문제 . 이 솔루션들은 문제 없습니다.
주문을 보존하면서 중복을 제거하기 위해 이 페이지의 다른 부분에 제시된 뛰어난 솔루션이 있습니다.
seen = set()
[x for x in seq if not (x in seen or seen.add(x))]
및 변동. 예:
seen = set()
[x for x in seq if x not in seen and not seen.add(x)]
는 단순하고 최소적이며 최적의 효율을 위해 올바른 해시를 도입하기 때문에 매우 인기가 있습니다. 큰 하는 것 .None
인 'seen.add(x)
논리적 표현에서 상수(따라서 초과/초과) 값은 단지 그 부작용 때문에 진부하거나 혼란스럽기 때문이다.
2. 1회 됩니다.2 . ... , 、 1 복 、 1 복 、 1 회 、 1 회 회 회 회회 。
놀랍게도, 이 주제에 대한 토론과 토론의 양을 고려할 때, 실제로 간과된 것처럼 보이는 코드에는 상당한 개선이 있습니다.그림과 같이 각 "테스트 앤 세트" 반복에는 2개의 해시 룩업이 필요합니다.멤버십을 테스트하는 첫 번째 해시 룩업x not in seen
seen.add(x)
첫 번째 조작은 두 번째 조작이 항상 성공한다는 것을 보증하기 때문에, 여기에는 불필요한 중복 작업이 있습니다.또한 전체적인 기법이 매우 효율적이기 때문에 과도한 해시 검색은 남은 작업 중 가장 비용이 많이 드는 부분이 될 수 있습니다.
3 신,, the, the,set
★★★★★★★★★★★★★★★★★★!
에서는, 「 」만을 호출하고 에 주의해 주세요.set.add
그렇게 하면 항상 세트 멤버십이 증가한다는 것을 알고 있습니다.set
그 자체는 복제를 거부할 기회가 없습니다.우리의 코드 스니펫은 본질적으로 그 역할을 스스로 침해하고 있습니다.명시적인 2단계 테스트 앤 세트 코드를 사용하는 것은 강도입니다.set
그 복제품 자체를 배제할 수 있는 핵심 능력을 가지고 있습니다.
코드 4. 「 」 、 「 」
다음 버전에서는 반복당 해시 룩업 횟수가 2회에서 1회로 절반으로 줄어듭니다.
seen = set()
[x for x in seq if len(seen) < len(seen.add(x) or seen)]
라이너가 1개 필요한 경우는, 다음과 같은 것이 도움이 됩니다.
reduce(lambda x, y: x + y if y[0] not in x else x, map(lambda x: [x],lst))
...은 효과가 있지만 내가 틀렸다면 정정해야 한다.
MizardX의 답변은 다양한 접근 방식을 제공합니다.
내가 큰 소리로 생각하면서 생각해낸 것은 다음과 같다.
mylist = [x for i,x in enumerate(mylist) if x not in mylist[i+1:]]
일종의 추악한 목록 이해 해킹을 할 수도 있어요
[l[i] for i in range(len(l)) if l.index(l[i]) == i]
with with with with with with with with with with with with with로 비교적 효과적인 _sorted_
a numpy
★★★★★★★★★★★★★★★★★★:
b = np.array([1,3,3, 8, 12, 12,12])
numpy.hstack([b[0], [x[0] for x in zip(b[1:], b[:-1]) if x[0]!=x[1]]])
출력:
array([ 1, 3, 8, 12])
l = [1,2,2,3,3,...]
n = []
n.extend(ele for ele in l if ele not in set(n))
세트의 O(1) 검색을 사용하여 요소를 새 목록에 포함할지 여부를 결정하는 제너레이터 식입니다.
단순한 재귀적 솔루션:
def uniquefy_list(a):
return uniquefy_list(a[1:]) if a[0] in a[1:] else [a[0]]+uniquefy_list(a[1:]) if len(a)>1 else [a[0]]
시퀀스에서 중복된 값을 제거하지만 나머지 항목의 순서는 유지합니다.범용 제너레이터 기능 사용.
# for hashable sequence
def remove_duplicates(items):
seen = set()
for item in items:
if item not in seen:
yield item
seen.add(item)
a = [1, 5, 2, 1, 9, 1, 5, 10]
list(remove_duplicates(a))
# [1, 5, 2, 9, 10]
# for unhashable sequence
def remove_duplicates(items, key=None):
seen = set()
for item in items:
val = item if key is None else key(item)
if val not in seen:
yield item
seen.add(val)
a = [ {'x': 1, 'y': 2}, {'x': 1, 'y': 3}, {'x': 1, 'y': 2}, {'x': 2, 'y': 4}]
list(remove_duplicates(a, key=lambda d: (d['x'],d['y'])))
# [{'x': 1, 'y': 2}, {'x': 1, 'y': 3}, {'x': 2, 'y': 4}]
x = [1, 2, 1, 3, 1, 4]
# brute force method
arr = []
for i in x:
if not i in arr:
arr.insert(x[i],i)
# recursive method
tmp = []
def remove_duplicates(j=0):
if j < len(x):
if not x[j] in tmp:
tmp.append(x[j])
i = j+1
remove_duplicates(i)
remove_duplicates()
1개의 라이너 리스트 이해:
values_non_duplicated = [value for index, value in enumerate(values) if value not in values[ : index]]
일상적으로 사용하는 경우 성능보다 미관을 중시하는 경우 내장 기능을 고려하십시오.pandas.Series.drop_duplicates
:
import pandas as pd
import numpy as np
uniquifier = lambda alist: pd.Series(alist).drop_duplicates().tolist()
# from the chosen answer
def f7(seq):
seen = set()
seen_add = seen.add
return [ x for x in seq if not (x in seen or seen_add(x))]
alist = np.random.randint(low=0, high=1000, size=10000).tolist()
print uniquifier(alist) == f7(alist) # True
타이밍:
In [104]: %timeit f7(alist)
1000 loops, best of 3: 1.3 ms per loop
In [110]: %timeit uniquifier(alist)
100 loops, best of 3: 4.39 ms per loop
이 방법은 순서를 유지하고 O(n)시간 내에 실행됩니다.기본적으로 중복되는 것이 발견되면 구멍을 만들어 바닥에 가라앉히는 것입니다.는 읽기 및 쓰기 포인터를 사용합니다.중복이 발견될 때마다 읽기 포인터만 진행되며 쓰기 포인터는 중복된 엔트리에 남아 덮어씁니다.
def deduplicate(l):
count = {}
(read,write) = (0,0)
while read < len(l):
if l[read] in count:
read += 1
continue
count[l[read]] = True
l[write] = l[read]
read += 1
write += 1
return l[0:write]
Import된 모듈 또는 세트를 사용하지 않는 솔루션:
text = "ask not what your country can do for you ask what you can do for your country"
sentence = text.split(" ")
noduplicates = [(sentence[i]) for i in range (0,len(sentence)) if sentence[i] not in sentence[:i]]
print(noduplicates)
출력:
['ask', 'not', 'what', 'your', 'country', 'can', 'do', 'for', 'you']
임플레이스 방식
모든 에 2차적인 입니다(이 정렬 됩니다).목록의 모든 요소에 대해 목록으로 선형 룩업이 있기 때문입니다(이 때문에 목록 재정렬 비용을 추가해야 합니다).del
단, 리스트의 끝에서 원점 방향으로 진행하면 왼쪽 서브리스트에 있는 각 용어를 삭제할 수 있습니다.
이 코드 아이디어는 단순합니다.
for i in range(len(l)-1,0,-1):
if l[i] in l[:i]: del l[i]
간단한 구현 테스트
In [91]: from random import randint, seed
In [92]: seed('20080808') ; l = [randint(1,6) for _ in range(12)] # Beijing Olympics
In [93]: for i in range(len(l)-1,0,-1):
...: print(l)
...: print(i, l[i], l[:i], end='')
...: if l[i] in l[:i]:
...: print( ': remove', l[i])
...: del l[i]
...: else:
...: print()
...: print(l)
[6, 5, 1, 4, 6, 1, 6, 2, 2, 4, 5, 2]
11 2 [6, 5, 1, 4, 6, 1, 6, 2, 2, 4, 5]: remove 2
[6, 5, 1, 4, 6, 1, 6, 2, 2, 4, 5]
10 5 [6, 5, 1, 4, 6, 1, 6, 2, 2, 4]: remove 5
[6, 5, 1, 4, 6, 1, 6, 2, 2, 4]
9 4 [6, 5, 1, 4, 6, 1, 6, 2, 2]: remove 4
[6, 5, 1, 4, 6, 1, 6, 2, 2]
8 2 [6, 5, 1, 4, 6, 1, 6, 2]: remove 2
[6, 5, 1, 4, 6, 1, 6, 2]
7 2 [6, 5, 1, 4, 6, 1, 6]
[6, 5, 1, 4, 6, 1, 6, 2]
6 6 [6, 5, 1, 4, 6, 1]: remove 6
[6, 5, 1, 4, 6, 1, 2]
5 1 [6, 5, 1, 4, 6]: remove 1
[6, 5, 1, 4, 6, 2]
4 6 [6, 5, 1, 4]: remove 6
[6, 5, 1, 4, 2]
3 4 [6, 5, 1]
[6, 5, 1, 4, 2]
2 1 [6, 5]
[6, 5, 1, 4, 2]
1 5 [6]
[6, 5, 1, 4, 2]
In [94]:
언급URL : https://stackoverflow.com/questions/480214/how-do-i-remove-duplicates-from-a-list-while-preserving-order
'source' 카테고리의 다른 글
현재 페이지의 Vuex 레코드를 삭제할 때 네비게이션을 처리하는 방법 (0) | 2022.09.06 |
---|---|
clang 오류: unknown 인수: '-mno-madd'(패키지 설치 실패) (0) | 2022.09.06 |
문자열을 분할하여 특정 문자를 구분하려면 어떻게 해야 하나요? (0) | 2022.09.06 |
URL 인코딩에서는 "&"(앰퍼샌드)를 "&" HTML 엔티티로 간주합니다. (0) | 2022.09.06 |
두 개의 Numpy 어레이를 동시에 섞는 더 좋은 방법 (0) | 2022.09.06 |