파이썬/파이썬 기초

[Python] List 배열 요소 중복 횟수 구하는 방법 (Counting duplicates in list)

Song 컴퓨터공학 2023. 6. 20. 22:42

List 안의 모든 요소들 중 중복 횟수 구하는 방법은 정말 많겠지만, 오늘 알아볼 방법은 대략 3가지 입니다.

  1. for, in 사용
  2. for, try-except 사용
  3. collections 모듈의 Counter 사용

그런데 위 방법들은 List 안의 "모든 요소"들의 중복 횟수를 구하는 방법입니다.

 

List 안의 "특정 요소"의 중복 횟수 구하는 방법도 2가지 알아볼 예정입니다.

  1. List.count()
  2. 모든 원소의 중복 횟수를 담은 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번 문제를 보며 마무리하겠습니다.

 

1157번: 단어 공부

알파벳 대소문자로 된 단어가 주어지면, 이 단어에서 가장 많이 사용된 알파벳이 무엇인지 알아내는 프로그램을 작성하시오. 단, 대문자와 소문자를 구분하지 않는다.

www.acmicpc.net

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 에서 출력해주면 됩니다.