파이썬으로 프로그래밍을 하다 보면 리스트에서 특정 값이 위치한 인덱스(index)를 찾아야 하는 경우가 매우 자주 발생합니다. 기본 내장 메서드인 index()를 사용하면 손쉽게 해결할 수 있지만, 이 메서드는 해당 값이 처음 나타나는 위치 하나만 반환한다는 한계가 있습니다.
만약 리스트 안에 같은 값이 여러 번 중복해서 존재하고, 그 모든 인덱스를 한꺼번에 구해야 한다면 다른 접근 방식이 필요합니다. 이번 글에서는 리스트에서 특정 값의 모든 인덱스를 찾는 대표적인 4가지 방법을 예제 코드와 함께 살펴보겠습니다.
1. filter() 함수 사용하기
filter() 함수와 람다(lambda) 표현식을 조합하면 인덱스 범위를 순회하면서 조건에 맞는 인덱스만 걸러낼 수 있습니다.
# filter() 함수를 사용하는 방법
# 리스트 초기화
test_list = [1, 3, 4, 3, 6, 7]
# 초기 리스트 출력
print('Original list : ' + str(test_list))
# filter()로 값이 3인 요소의 인덱스 찾기
res_list = list(filter(lambda x: test_list[x] == 3, range(len(test_list))))
# 결과 리스트 출력
print('New indices list : ' + str(res_list))
range(len(test_list))로 생성된 각 인덱스를 람다 함수에 전달하고, 해당 인덱스의 값이 3과 일치하는 경우만 필터링하여 최종적으로 인덱스 리스트를 얻습니다.
2. enumerate() 함수 사용하기
enumerate()는 리스트를 순회하면서 인덱스와 값을 동시에 꺼내올 수 있어 가장 파이썬다운(Pythonic) 방식으로 평가받습니다.
# enumerate() 함수를 사용하는 방법
# 리스트 초기화
test_list = [1, 3, 4, 3, 6, 7]
# 초기 리스트 출력
print('Original list : ' + str(test_list))
# enumerate()로 값이 3인 요소의 인덱스 찾기
res_list = [i for i, value in enumerate(test_list) if value == 3]
# 결과 리스트 출력
print('New indices list : ' + str(res_list))
리스트 컴프리헨션과 결합하면 코드가 간결해지고 가독성도 뛰어나며, 불필요한 인덱스 계산 없이 바로 순회할 수 있어 성능 면에서도 유리합니다.
3. 리스트 컴프리헨션(List Comprehension) 사용하기
인덱스 범위를 직접 생성한 뒤 조건 검사를 통해 원하는 인덱스만 추출하는 방식입니다.
# 리스트 컴프리헨션을 사용하는 방법
# 리스트 초기화
test_list = [1, 3, 4, 3, 6, 7]
# 초기 리스트 출력
print('Original list : ' + str(test_list))
# 리스트 컴프리헨션으로 값이 3인 요소의 인덱스 찾기
res_list = [i for i in range(len(test_list)) if test_list[i] == 3]
# 결과 리스트 출력
print('New indices list : ' + str(res_list))
enumerate() 방식과 결과는 동일하지만, 인덱스를 명시적으로 다루고 싶거나 인덱스 기반의 추가 연산이 필요한 경우에 유용하게 활용할 수 있습니다.
4. 반복문을 이용한 일반적인 방법(Naive Method)
별도의 함수 없이 기본적인 for 반복문과 조건문만으로도 충분히 구현할 수 있습니다. 초보자에게 로직이 가장 직관적으로 다가오는 방식입니다.
# 반복문을 사용하는 일반적인 방법
# 리스트 초기화
test_list = [1, 3, 4, 3, 6, 7]
# 초기 리스트 출력
print('Original list : ' + str(test_list))
# 반복문으로 값이 3인 요소의 인덱스 찾기
res_list = []
for i in range(0, len(test_list)) :
if test_list[i] == 3 :
res_list.append(i)
# 결과 리스트 출력
print('New indices list : ' + str(res_list))
빈 리스트를 먼저 선언한 후, 리스트의 길이만큼 반복하면서 조건에 맞는 인덱스를 append()로 추가하는 단순한 구조입니다.
실행 결과
네 가지 방법 모두 아래와 동일한 결과를 출력합니다. 값 3은 인덱스 1과 3 위치에 존재하므로 두 개의 인덱스가 반환됩니다.
Original list : [1, 3, 4, 3, 6, 7]
New indices list : [1, 3]
Original list : [1, 3, 4, 3, 6, 7]
New indices list : [1, 3]
Original list : [1, 3, 4, 3, 6, 7]
New indices list : [1, 3]
Original list : [1, 3, 4, 3, 6, 7]
New indices list : [1, 3]
마무리 및 정리
리스트에서 특정 값의 모든 인덱스를 찾는 네 가지 방법을 비교하면 다음과 같습니다.
- enumerate() + 리스트 컴프리헨션: 가독성과 성능의 균형이 좋아 실무에서 가장 널리 권장되는 방식
- filter(): 함수형 프로그래밍 스타일을 선호하는 경우 적합
- 반복문: 로직을 단계별로 이해하기 쉬워 학습 목적이나 복잡한 조건 처리에 유용
상황에 맞는 방법을 선택하여 코드의 가독성과 효율성을 높여보시기 바랍니다.