배워서 남 주자

개발 및 개발환경/Python

[Python] List 내의 중복된 element 제거하기

신라면순한맛 2022. 9. 21. 23:00

이번 포스팅에서는 List 내의 중복을 제거하는 방법을 알아보도록 하겠습니다.

 


 

가장 간단한 경우로, list가 scalar형 값들을 가지고 있는 경우 list와 set으로 중복을 제거할 수 있습니다. 기본적으로 set은 말 그대로 집합을 의미하죠. 수학에서도 그렇지만 집합 내에서는 index가 따로 있지 않고 그저 그 집합안에 있다, 없다가 중요하기 때문에 이를 이용해 중복을 제거합니다.

 

예를 들어, 수학에서는 $$ \{1,2,3,1,1,2\} = \{1,2,3\} = \{3,2,1\}$$ 인 것처럼, 중복된 값을 표현하는 것이 의미없을 뿐만 아니라, 표기하는 순서가 다르다고 절대 다른 집합을 가리키지 않습니다.

 

Python에서도 마찬가지인데요. set을 취해주면 말 그대로 set type으로 변환이 되기 때문에, list를 겉에 한 번 더 씌워주면서 최종적으로 list 형으로 결과가 나오길 원하는 것입니다.

vara = [1, 2, 3, 1, 1, 2]

varb = list(set(vara))
print(varb)			# [1, 2, 3]

 

 

만약에 list들의 list로 주어진 경우라면 이 때도 같은 방법으로 중복이 제거가 될까요? 아쉽게도 그렇게 되지는 않습니다.

vara = [[1, 2, 3], [4, 5, 6], [1, 2, 3]]

varb = list(set(vara))
# Traceback (most recent call last):
# File "<string>", line 3, in <module>
# TypeError: unhashable type: 'list'

 

오류에서 등장한 "unhashable"은 말 그대로 해싱이 불가능하다는 의미로, 조금 더 알아듣기 쉬운 말로 표현하면 다음과 같습니다. Set을 씌우는 대상은 immutable type의 변수여야 하는데, 맨 위 예에서의 정수형 변수는 immutable이어서 가능했던 반면, list type의 경우 변형이 가능한 mutable type이기 때문에 set 입장에서 hashing이 안되는 type이라는 오류를 발생시킨 것입니다. 그래서 vara 안을 이루는 element가 list가 아니라 immutable인 tuple type이었다면, 우리가 바라는대로 중복제거가 가능합니다.

vara = [[1, 2, 3], [4, 5, 6], [1, 2, 3]]
vara = [tuple(x) for x in vara]

varb = list(set(vara))
print(varb)			# [(1, 2, 3), (4, 5, 6)]

 

물론 그렇다고 매번 list들의 list로 주어져 있을 때 tuple로 바꿔서 처리하는 것은 불편한 작업일 수도 있습니다. 약간 tricky하게 다음과 같이 해결할 수도 있습니다. 

vara = [[1, 2, 3], [4, 5, 6], [1, 2, 3]]

varb = {str(val):val for val in vara}.values()
varb = list(varb)
print(varb)			# [[1, 2, 3], [4, 5, 6]]

 

즉, vara 안의 list를 string화 시켜서 dictionary의 key로 주면, 같은 list가 들어와도 중복으로 counting이 안되기 때문에 중복제거가 가능합니다. str뿐만 아니라 bytes등으로도 encoding하면 같은 결과를 얻을 수 있습니다.

 

 


 

이상으로 이번 포스팅을 마치겠습니다.