List 안의 모든 요소들 중 중복 횟수 구하는 방법은 정말 많겠지만, 오늘 알아볼 방법은 대략 3가지 입니다.
- for, in 사용
- for, try-except 사용
- collections 모듈의 Counter 사용
그런데 위 방법들은 List 안의 "모든 요소"들의 중복 횟수를 구하는 방법입니다.
List 안의 "특정 요소"의 중복 횟수 구하는 방법도 2가지 알아볼 예정입니다.
- List.count()
- 모든 원소의 중복 횟수를 담은 dict에서 찾기
for, in 사용
array = ["F", "D", "A", "C", "A", "C", "F", "B", "C", "E", "C", "C", "F", "A", "B", "E", "F", "E"]
count = {}
for value in array:
if value in count:
count[value] += 1
else:
count[value] = 1
print(array)
print(count)
# Output
# ['F', 'D', 'A', 'C', 'A', 'C', 'F', 'B', 'C', 'E', 'C', 'C', 'F', 'A', 'B', 'E', 'F', 'E']
# {'F': 4, 'D': 1, 'A': 3, 'C': 5, 'B': 2, 'E': 3}
리스트의 데이터를 순회하면서 "in" 을 통해 리스트 안에 그 원소가 있다면 1을 더하고 아니면 1개만 있는 거니까 1을 대입해서 각 원소별로 반복되는 숫자를 모두 나타나게 됩니다. 가장 직관적인 방법입니다.
for, try-except 사용
array = ["F", "D", "A", "C", "A", "C", "F", "B", "C", "E", "C", "C", "F", "A", "B", "E", "F", "E"]
count = {}
for value in array:
try: count[value] += 1
except: count[value] = 1
print(array)
print(count)
# Output
# ['F', 'D', 'A', 'C', 'A', 'C', 'F', 'B', 'C', 'E', 'C', 'C', 'F', 'A', 'B', 'E', 'F', 'E']
# {'F': 4, 'D': 1, 'A': 3, 'C': 5, 'B': 2, 'E': 3}
거의 동일하게 리스트의 원소를 사용해 순회하면서 try와 except 를 사용해 이를 수행합니다. 다른 언어만 다뤄서 파이썬이 익숙하지 않다면 "도대체 어떤 걸 기준으로 try를 하고, 언제 except 를 수행하는거지?" 라는 생각이 들 수도 있습니다.
먼저, try 블럭 내에 있는 count[value] += 1 은 count 딕셔너리에서 value라는 키의 값을 1 증가시키려고 시도합니다. 만약 count 딕셔너리에 value 키가 이미 존재하는 경우 이 연산은 성공하고 키의 값이 1 증가됩니다. 하지만 value 키가 존재하지 않는 경우 1이 되는 것이 아니라 초기화 안된 변수에 값을 더하는 것과 같기 때문에 실행되지 않고 except 로 이동하여 1로 새로 추가하게 됩니다. 이렇게 함으로써 전체 A~F 에 대하여 한 번만 있는 것은 1이 나오고, 여러번 나오는 것들은 value 키가 업데이트 되면서 중복 횟수를 반환하게 됩니다.
Collection 모듈의 Counter 사용
from collections import Counter
array = ["F", "D", "A", "C", "A", "C", "F", "B", "C", "E", "C", "C", "F", "A", "B", "E", "F", "E"]
count = Counter(array)
print(array)
print(count)
print(dict(count))
# Output
# ['F', 'D', 'A', 'C', 'A', 'C', 'F', 'B', 'C', 'E', 'C', 'C', 'F', 'A', 'B', 'E', 'F', 'E']
# Counter({'C': 5, 'F': 4, 'A': 3, 'E': 3, 'B': 2, 'D': 1})
# {'F': 4, 'D': 1, 'A': 3, 'C': 5, 'B': 2, 'E': 3}
collections 모듈에 있는 Counter 를 사용하면 쉽게 List 안의 모든 요소의 중복 횟수를 셀 수 있습니다. Counter 객체를 dict() 를 통해 dict 형식으로 변환하여 사용할 수도 있습니다.
이 아래는 특정 요소의 중복 횟수를 찾는 방법입니다.
List.count()
array = ["F", "D", "A", "C", "A", "C", "F", "B", "C", "E", "C", "C", "F", "A", "B", "E", "F", "E"]
print(array)
print("요소 'C' 갯수 : ", array.count("C"))
# Output
# ['F', 'D', 'A', 'C', 'A', 'C', 'F', 'B', 'C', 'E', 'C', 'C', 'F', 'A', 'B', 'E', 'F', 'E']
# 요소 'C' 갯수 : 5
List 형의 count() 라는 내장 함수를 통해 List 안의 특정 요소 개수를 카운트해 중복 횟수를 구할 수 있습니다.
모든 원소의 중복횟수를 담은 dict 에서 찾기
array = ["F", "D", "A", "C", "A", "C", "F", "B", "C", "E", "C", "C", "F", "A", "B", "E", "F", "E"]
count = {}
for value in array:
try: count[value] += 1
except: count[value ] = 1
print(array)
print("요소 'C' 갯수 : ", count["C"])
# Output
# ['F', 'D', 'A', 'C', 'A', 'C', 'F', 'B', 'C', 'E', 'C', 'C', 'F', 'A', 'B', 'E', 'F', 'E']
# 요소 'C' 갯수 : 5
혹은 맨 처음 모든 원소에 대해서 중복 횟수를 구해놓은 dict 에서 인덱스를 통해서 접근하여 찾는 방법이 있습니다.
마지막으로 백준 1157번 문제를 보며 마무리하겠습니다.
word = input().upper()
unique = list(set(word))
count_list = []
for i in unique:
count = word.count(i)
count_list.append(count)
if count_list.count(max(count_list)) > 1:
print('?')
else:
max_index = count_list.index(max(count_list))
print(unique[max_index])
이 문제의 경우 대소문자 구분 없이 세야했기 때문에 .upper() 를 사용해 모두 대문자로 만들어주고 중복된 원소를 제거하는 set 으로 만들어서 종류에 대한 리스트를 만듭니다. 그 이후 count 횟수를 셀 리스트를 하나 만들어서 unique의 원소에 대해서 순회를 하면서 list.count 를 통해 그 숫자를 count_list 에 append 하게 됩니다. 예를 들어 "SongBlog" 라는 문자열이 들어갔다면 가장 먼저 "SONGBLOG" 로 바꾸게 되고, 그 이후에는 중복된 요소들이 제거된 set이 생깁니다. 테스트를 해보니 ['O', 'L', 'N', 'B', 'G', 'S'] 로 저장되네요. 그리고 이 원소들에 대해서 원래 입력을 받은 word 에서 카운트 한 숫자들을 count_list에 추가합니다.
최댓값이 같은 경우가 있다면 ? 를 출력해야 하기 때문에 max(count_list) [최대 반복 횟수] 가 나온 횟수를 count_list 내에서 count 해준 값이 1보다 크다면 이라는 조건을 통해 ? 를 출력하고 그 외의 경우에는 최댓값을 unique 에서 출력해주면 됩니다.
'파이썬 > 파이썬 기초' 카테고리의 다른 글
[Python] 람다 표현식 ( lambda expression ) (0) | 2023.08.18 |
---|---|
[Python] Numpy 라이브러리 사용법 총 정리 [지속 업데이트] (0) | 2023.07.30 |
[Python] join 함수 : 구분자 문자열 리스트 결합하기(이어붙이기) (0) | 2023.07.04 |