2025.05.22 - [프로그래밍] - [PCCE] LV3 파이썬 완전정복: Part 1 PCCE 시험 개요와 LV3 등급 분석
2025.05.22 - [프로그래밍] - [PCCE] LV3 파이썬 완전정복: Part 2: 변수, 자료형, 연산자 – Python 기본 문법 ①
2025.05.23 - [프로그래밍] - [PCCE] LV3 파이썬 완전정복: Part 3 조건문 – 흐름 제어 기초
2025.05.24 - [프로그래밍] - [PCCE] LV3 파이썬 완전정복: Part 4 반복문 – while, for, 중첩 반복
데이터를 모아 담는 그릇 – 리스트의 활용성
변수는 하나의 값만 담지만, **리스트(list)**는 여러 값을 하나로 묶어 관리할 수 있습니다. 예를 들어 성적 30개를 개별 변수로 다루는 건 비효율적이지만, 리스트 하나에 넣으면 반복문으로 손쉽게 처리할 수 있죠. 리스트는 파이썬에서 매우 강력하고 자주 쓰이는 자료구조이며, PCCE에서도 리스트를 다루는 문제가 빠짐없이 출제됩니다. 특히 2차원 리스트(리스트의 리스트, 행렬 구조)는 표나 격자 형태 데이터를 나타낼 때 쓰입니다. 이번 파트에서는 Python의 리스트 사용법(생성, 인덱싱, 2차원 리스트 처리 등)을 정리하고, PCCE에서 어떤 리스트 문제가 나오는지 살펴보겠습니다.
리스트 기본과 2D 리스트
1. 리스트 생성과 기본 연산: Python에서 리스트는 대괄호 []를 사용하여 생성합니다. 예를 들면:
# 코드 예시 |
scores = [90, 85, 72, 100, 98] |
이렇게 하면 5개의 정수를 담은 리스트 scores가 만들어집니다. 리스트는 순서가 있는 시퀀스이므로, 각 원소에는 0부터 시작하는 인덱스(index)가 매겨집니다. 위 scores에서 scores[0]은 90, scores[1]은 85, ... scores[4]는 98입니다. 인덱스를 사용해 값을 읽거나 쓸 수 있습니다:
# 코드 예시 |
print(scores[2]) # 72 출력 scores[2] = 75 # 세 번째 점수를 75로 수정 |
또한 len(scores)로 리스트 길이를 구할 수 있어, 동적인 처리에 유용합니다.
리스트 기본 연산으로는 추가, 삭제, 슬라이싱 등이 있습니다:
- append(x): 리스트 끝에 새 원소 x를 추가.
- insert(i, x): 인덱스 i 위치에 x를 삽입 (그 뒤 원소들은 한 칸 밀립니다).
- pop(i): 인덱스 i 위치의 원소를 제거하며 반환. pop()이라고 인덱스 없이 쓰면 마지막 원소를 제거합니다.
- remove(x): 값 x를 찾아 제거 (동일 값 여러 개면 첫 번째만 제거).
- 슬라이싱 lst[a:b]: 인덱스 a부터 b-1까지 부분리스트를 취함. 예를 들어 scores[1:4]는 [85, 75, 100]. 슬라이싱은 리스트를 잘라내거나 특정 부분을 대체할 때 쓰입니다. (주의: [a:b]는 a부터 b-1까지, a나 b를 생략하면 처음부터 혹은 끝까지로 간주)
2. 리스트 순회(반복): Part 4에서 다룬 for 루프로 리스트를 쉽게 순회할 수 있습니다. for item in scores:는 각 점수를 순서대로 가져오고, for i in range(len(scores)):는 인덱스로 순회하는 방식입니다. 두 방법 모두 익혀두세요. 또한 **리스트 내포(list comprehension)**이라는 Python 특유의 축약 문법도 있지만, PCCE에서는 기본 가독성 높은 코드가 좋으므로 내포는 꼭 필요할 때만 써도 됩니다. (예: [x*2 for x in list]는 리스트 각 원소 2배로 새 리스트 생성)
3. 2차원 리스트: 2차원 리스트는 리스트의 리스트입니다. 행렬 형태로 상상하면 됩니다. 예를 들어 3x3 격자를 만들려면:
# 코드 예시 |
board = [ [1, 2, 3], [4, 5, 6], [7, 8, 9] ] |
이렇게 리스트 안에 3개의 하위 리스트가 들어있는 구조입니다. board는 행이 3개, 열이 3개인 2D 리스트라서, board[0]는 [1,2,3], board[1][2]는 6 등을 의미합니다. 2차원 리스트는 인덱스가 2개 필요한데, 일반적으로 board[row][col]로 표기합니다.
2차원 리스트를 순회하려면 중첩 루프를 사용합니다:
# 코드 예시 |
for i in range(len(board)): # 각 행 for j in range(len(board[i])): # 해당 행의 각 열 print(board[i][j], end=" ") print() |
이 코드는 1 2 3, 4 5 6, 7 8 9를 행렬 형태로 출력합니다. Python에서는 for row in board: 그리고 for val in row: 식으로 더 간단히 중첩 없이도 가능합니다:
# 코드 예시 |
for row in board: for val in row: print(val, end=" ") print() |
위와 동일한 동작을 합니다. 편한 방식으로 쓰면 되고, 상황에 따라 인덱스가 필요하면 첫 번째 방법, 값만 필요하면 두 번째 방법을 쓰면 됩니다.
4. 유용한 함수들: 리스트 관련 몇 가지 유용한 파이썬 함수/메서드도 알아둡시다 (PCCE 시험에서 직접 호출하는 것도 허용일 수 있음):
- sum(lst): 숫자 리스트의 합계를 반환.
- max(lst), min(lst): 리스트의 최댓값/최솟값 반환.
- sorted(lst): 리스트를 정렬한 새 리스트 반환 (원본 유지), lst.sort()는 제자리 정렬(원본 변경).
- list(map(int, input().split())): 여러 숫자 입력을 리스트로 받는 관용구. (모든 언어 중 파이썬이 입력 파싱이 편한 편이죠.)
5. 리스트의 활용 예: 리스트는 다양한 문제에서 활용됩니다. 예를 들어:
- 점수 목록에서 평균 구하기, 최고/최저 점수 구하기.
- 문자열을 한 글자씩 리스트에 넣고 처리하거나, 문자열 여러 줄을 2D 리스트로 다루기.
- 구현 문제에서 상태를 저장 (예: 게임 보드, 방문 체크 등)하기.
- 데이터 변환 (예: 정수 n의 각 자릿수를 리스트로 분리 등).
- 알고리즘용 자료구조로서 스택/큐 동작 (append/pop으로 스택, collections.deque로 큐 등) – Lv3에서는 기본 리스트로 충분.
실습 예제 코드: 리스트와 2차원 리스트 조작
여러 상황별로 리스트를 다루는 예제를 통해 이해를 다져보겠습니다.
# 코드 예시 |
# 1. 리스트 생성과 기본 연산 nums = [10, 20, 30] nums.append(40) # 끝에 40 추가 -> [10,20,30,40] nums.insert(2, 25) # 인덱스 2에 25 삽입 -> [10,20,25,30,40] print("리스트:", nums) # 출력: [10, 20, 25, 30, 40] print("길이:", len(nums)) # 출력: 5 nums.pop() # 마지막 원소 제거 (40 제거) nums.remove(25) # 값 25 제거 -> [10, 20, 30] print("수정된 리스트:", nums) # 출력: [10, 20, 30] # 2. 리스트 순회와 합계 계산 scores = [70, 85, 90, 45, 100] total = 0 for s in scores: total += s avg = total / len(scores) print("총점:", total, "평균:", avg) # 출력: 총점: 390 평균: 78.0 # 3. 최댓값, 최솟값 찾기 max_score = scores[0] min_score = scores[0] for s in scores: if s > max_score: max_score = s if s < min_score: min_score = s print("최고점:", max_score, "최저점:", min_score) # 출력: 최고점: 100 최저점: 45 # (파이썬 내장 함수 사용 시) print("최고점:", max(scores), "최저점:", min(scores)) # 같은 결과 # 4. 2차원 리스트 생성 및 출력 matrix = [ [1, 2, 3], [4, 5, 6] ] # 2행 3열 (2x3) 행렬 print("행 개수:", len(matrix), "열 개수:", len(matrix[0])) # 출력: 행 개수: 2 열 개수: 3 for i in range(len(matrix)): for j in range(len(matrix[i])): print(matrix[i][j], end=" ") print() # 출력: # 1 2 3 # 4 5 6 # 5. 2차원 리스트 데이터 처리 (예: 각 행의 합) row_sums = [] for row in matrix: row_sum = sum(row) row_sums.append(row_sum) print("각 행의 합:", row_sums) # 출력: 각 행의 합: [6, 15] # 6. 도전: 리스트 컴프리헨션 (심화, 이해만) # 1~5 제곱 리스트 만들기 squares = [x*x for x in range(1, 6)] print("제곱 리스트:", squares) # 출력: [1, 4, 9, 16, 25] |
설명:
- 1번: nums 리스트에 대해 append, insert, pop, remove 등을 해봤습니다. 각 연산 후 리스트 상태를 출력하여 변화 과정을 확인할 수 있습니다. 25를 중간에 넣었다가 pop으로 40 빼고 remove로 25를 제거하여 결과 [10,20,30]을 얻었죠. 이런 리스트 조작은 PCCE의 빈칸 채우기나 디버깅으로 출제될 수 있습니다. 예를 들어, 원소 삽입 위치나 삭제 논리를 제대로 구현하는지를 물어볼 수 있죠.
- 2번: 리스트 합계와 평균을 계산하는 예제입니다. 점수 리스트를 for로 순회하면서 total을 누적했습니다. 결과 평균은 78.0으로 나옵니다. 기본 중의 기본이지만, 종종 수험생들이 합계 초기값을 0으로 안 해주거나, sum 함수를 모르거나, 평균 계산 시 float 처리를 빼먹는 실수를 합니다. Python에서는 정수/정수 나누기도 float 결과가 나오므로 390/5 = 78.0 잘 나오지만, 만약 C언어였다면 int/int로 78이 나와버리죠. 이런 언어별 차이도 알고 있어야 다른 언어 코드 디버깅 문제를 풀 수 있습니다. (PCCE는 언어 선택형이라, Python 코드뿐 아니라 C++/Java 코드가 디버깅 문제로 나오기도 합니다. 하지만 기본 원리는 같으니 걱정 말고 이해 위주로 봅시다.)
- 3번: 리스트의 최대값과 최소값 찾기 알고리즘을 작성했습니다. 먼저 리스트 첫 번째 값을 초기 최대/최소로 놓고, for문 돌면서 갱신하는 패턴입니다. PCCE에서 이런 형태의 문제는 거의 반드시 나온다고 봐도 됩니다. 기출에서도 리스트 숫자들 중 최댓값 찾기, 혹은 특정 조건의 최댓값(예: 짝수 중 최대)을 찾는 문제가 있었습니다. 직접 구현해보는 연습도 하고, Python에서는 max()와 min()으로 쉽게 구할 수도 있다는 것도 알아둡니다. (시험에서 내장함수 써도 되냐 안되냐는 문제 지시를 따르세요. 별도 언급 없으면 써도 됩니다. 단, 직접 구현하는 문제면 빈칸에 비교코드 채우도록 유도할 수 있으니 그땐 스스로 해야 합니다.)
- 4번: 2차원 리스트 matrix를 만들고, 행/열 개수를 len으로 구한 뒤, 이중 루프로 출력했습니다. 결과 형태를 보면 2행 3열 데이터 구조가 잘 출력되었습니다. 인덱싱을 두 번 하는 것이 처음엔 헷갈릴 수 있는데, 연습으로 익혀야 합니다. 특히 len(matrix)는 행 개수, len(matrix[0])는 열 개수라는 점 기억해두세요 (단, 2차원 리스트가 일반적인 행렬 형태일 때 가능한 이야기고, 혹시 가변 길이 행이면 각 행 길이가 다를 수도 있음을 염두에 두세요).
- 5번: 2차원 리스트 응용으로, 각 행의 합을 구해 row_sums 리스트에 저장하는 예를 들었습니다. [1,2,3] 합 6, [4,5,6] 합 15이니 결과 [6,15]가 나오죠. 이처럼 2차원 데이터를 입력받아 행별 계산, 열별 계산 등을 하는 문제가 PCCE에 나올 수 있습니다. 예를 들어 "NxM 성적표에서 각 학생의 총점 구하기" 같은 형태로 말이죠. 이런 문제는 2중 루프 또는 적절한 Python 내장 활용으로 풀면 됩니다 (sum(row)처럼). 여기서는 sum(row)로 각 행의 합을 구했습니다. 만약 열별 합을 구하려면 바깥 루프를 열 인덱스로 돌리고, 내부에서 각 행을 보면서 해당 열 값을 더하는 식으로 짤 수도 있습니다.
- 6번 (심화): 리스트 컴프리헨션을 맛보기로 소개했습니다. 1부터 5까지 숫자의 제곱을 담은 리스트를 축약 문법으로 만들었는데, 결과 [1,4,9,16,25]가 잘 나옵니다. 컴프리헨션은 Pythonic한 문법이지만, 처음엔 가독성이 떨어질 수 있어요. PCCE에서는 굳이 이런 문법을 쓰기보단, 풀어서 쓰는 걸 권하지만, 알고 있어야 남이 쓴 코드를 이해할 때 도움이 됩니다. (혹시 기출 문제 해설 블로그 등을 보면 이 문법을 쓰는 경우가 있어요.)
PCCE 출제 포인트 분석: 리스트 분야
PCCE에서 리스트를 다루는 문제 유형은 아주 다양합니다. 그 중 대표적 포인트 몇 가지:
- 배열 기초 처리: 배열(리스트)의 값들을 순차적으로 처리하는 문제. 예를 들어 "N개의 정수 입력받아 거꾸로 출력하기", "배열 두 배로 만들기" 등이 있습니다. 이러한 문제는 리스트 인덱싱이나 append, 그리고 반복문 이해를 묻습니다. 단순해 보이지만 초보자는 인덱스 범위를 잘못 써서 IndexError를 낼 수 있습니다. 예를 들어 마지막 원소 인덱스는 len(lst)-1인데, 잘못해서 len(lst)까지 접근하려 하면 오류죠. PCCE 디버깅문제로 "리스트 범위 오류 수정"도 충분히 나올 수 있습니다.
- 검색 및 조건 필터링: 리스트에서 특정 조건을 만족하는 값 찾기 또는 개수 세기 문제입니다. 예를 들어 기출 중 "리스트에서 50 이상인 숫자 개수 세기" 같은 문제가 있었습니다. 이건 간단히 for 돌며 if 조건 체크하고 count++ 하면 됩니다. 또 다른 예로 "문자 리스트에 특정 문자가 몇 개 포함되었는지" 묻기도 하죠. 이 때 문자는 문자열이 아니라 리스트로 주어지기도 합니다 (예: ['a','b','c','a']에서 'a' 몇 개?). Python에선 list.count(x) 메서드로 바로 개수를 얻을 수 있지만, 수동으로 세라고 할 수도 있습니다. 정확도와 꼼꼼함이 포인트예요.
- 정렬 및 특정 순서 출력: 리스트 정렬을 요구할 수 있습니다. 예를 들어 "주어진 숫자들 오름차순 정렬하여 출력" 같은 건 기본이죠. Python에서는 sorted() 쓰면 한 줄이지만, 기초 역량 평가를 위해 버블정렬이나 선택정렬 한 단계 정도를 직접 코딩하게 할 수도 있습니다. (Lv3에서는 요구하지 않을 수도 있으나, range(len(lst)) 2중 루프 돌아 swap 하는 코드는 배워두면 좋아요.) 또한 정렬된 리스트에서 최댓값, 2번째 최댓값 등을 찾는 문제도 있습니다. 예를 들어 기출 8번 “창고 정리” 문제는 같은 물건을 합쳐 쌓고 가장 수량 많은 물건 이름을 출력하는 내용이었는데, 거기서 리스트 2개(물건이름 리스트, 수량 리스트)를 가지고 처리했습니다. 최종 단계에서 가장 큰 수량을 찾아 대응 물건명을 출력하는데, 이를 찾기 위해 리스트에서 max와 인덱스를 활용했죠.
- 2차원 배열 탐색: 2차원 리스트 (행렬)에서 뭔가 찾거나 계산하는 문제가 종종 있습니다. 기출 9번 *“이웃한 칸”*은 2D 배열에서 특정 셀 주변의 같은 색 칸 수를 세는 문제였고, 10번 “데이터 분석” 문제는 보다 복잡한 2D 데이터 처리였다고 합니다. 일반적으로 2차원 배열 문제의 포인트는 인덱스 관리와 경계 처리입니다. 즉, (i,j) 기준으로 상하좌우를 볼 때 i-1이 -1로 가면 안 되고, i+1이 행 크기 넘으면 안 되고... 이런걸 조건문으로 다루는 거죠. 또한 시뮬레이션 유형 (Part 8에서 상세히)도 보통 2D 그리드에서 일어나는 일들을 코드로 옮기는 형태가 많습니다. 미리 연습해둘 것은: 행렬에서 행/열 합 구하기, 특정 패턴 찾기(예: 행에 0이 있으면 카운트), 또는 두 행렬 더하기 같은 기본 조작 등입니다.
- 병합 및 분할: 두 리스트를 합치는 문제 또는 한 리스트를 분리하는 문제도 나올 수 있습니다. 예를 들어 "두 개의 정렬된 리스트를 병합하여 정렬 유지하기" 같은 건 자료구조 수준일 수도 있지만, 간단히 뒤에 붙여 정렬하는 정도로 낼 수 있어요. 또는 문자열 처리 문제에서 문자열을 한 글자씩 리스트로 만들어 뒤집거나 하는 식으로 리스트를 매개로 사용하기도 합니다. (Python에서는 문자열도 시퀀스라 리스트처럼 다룰 수 있지만, Java/C++에서는 char 배열 등으로 변환해서 해야하죠. 여러 언어를 섭렵하면 이러한 구현 차이를 알게 됩니다. PCCE는 한 언어만 잘해도 되지만, 다양한 접근법을 알아두면 응용력에 좋습니다.)
정리하면, 리스트 파트에서는 데이터를 저장하고 처리하는 능력을 평가합니다. 변수들이 많아질 때 배열로 모아서 처리하는 게 효율적이므로, 그 접근을 자연스럽게 할 수 있어야 하죠. 그리고 2차원 리스트는 현실 세계 표 형태 데이터를 다루기 때문에, 행렬 인덱싱에 익숙해지는 게 중요합니다.
마무리 요약 및 꿀팁
리스트(배열)는 코딩에서 없어서는 안 될 도구입니다. 값을 많이 다룰 땐 리스트로 처리하는 게 기본이며, 알고리즘 문제 풀 때도 리스트를 모르면 거의 아무것도 못 합니다. 이번 파트에서 다룬 내용을 요약하면: **“리스트를 생성하고, 인덱스로 접근/수정하며, 반복문으로 순회하고, 2차원 리스트도 인덱스 2개로 접근한다”**입니다. Level 3에서는 복잡한 자료구조보다는 이 정도 리스트 활용도를 확실히 보는 수준일 것입니다.
꿀팁:
- 인덱스 주의: 프로그래밍 언어 대부분이 0-indexed라는 것(첫 원소 인덱스가 0)을 꼭 기억하세요. 종종 인간은 1부터 세는 습관 때문에, 루프를 1부터 돌리거나 마지막 인덱스를 len-1이 아닌 len으로 착각하는 경우가 있습니다. 항상 리스트 길이가 N이면 유효 인덱스 범위는 [0, N-1]이라는 것을 되뇌세요.
- 임의 접근 vs 탐색: 리스트는 원하는 위치를 바로 접근 가능하지만, 값을 찾으려면 처음부터 순회해야 합니다. PCCE 문제에서 리스트에 값 저장 후 특정 값 위치 찾는 경우, 그냥 for문 돌며 찾으면 됩니다. (이게 O(N)이지만 N이 크지 않아 괜찮습니다.) 나중에 Lv4나 PCCP 가면 이진 탐색도 배우겠지만, Lv3는 선형 탐색으로 충분합니다.
- Deep copy vs shallow copy: 2차원 리스트를 다룰 때 한 가지 팁은, 리스트를 복사할 때 얕은 복사/깊은 복사 개념입니다. 예를 들어 matrix2 = matrix1 하면 같은 객체를 가리키고, matrix2 = matrix1[:] 하면 1차 리스트는 복사되지만 내부 행 리스트는 같은 레퍼런스를 가리킵니다. 완전 복사는 copy.deepcopy() 등이 필요합니다. PCCE Lv3에서 직접 이 상황이 나올 가능성은 낮지만, 코딩 중에 2차원 리스트를 복제해야 할 땐 주의해야 한다는 점만 알고 넘어갑시다.
추천 연습 문제
- [PCCE 기출문제] 8번: 창고 정리 – 같은 물건을 한 칸으로 합쳐 저장하고, 가장 개수가 많은 물건의 이름을 찾는 문제입니다. 1차원 리스트 2개(storage와 num)를 다루며, 중복을 합치기 위해 새로운 리스트(clean_storage, clean_num)를 만드는 작업을 연습할 수 있습니다. 이 문제는 리스트 추가/갱신, 이중 루프, 최대값 찾기까지 종합적으로 연습됩니다.
- [PCCE 기출문제] 9번: 이웃한 칸 – 2차원 리스트(격자판)에서 인접한 같은 색 칸의 개수를 세는 문제입니다. 이 문제를 풀면서 2중 인덱스 접근과 경계 조건을 다뤄보세요. (힌트: dx,dy 리스트를 [-1,1,0,0] 이런 식으로 만들어 4방향을 루프로 처리하면 효율적)
- 프로그래머스 Lv0: 직각삼각형 출력하기 – N을 입력받아 높이 N의 왼쪽 정렬된 '*' 직각삼각형을 출력하는 문제. 2중 루프와 리스트/문자열 출력이 혼합된 형태라 연습됩니다.
- 프로그래머스 Lv1: K번째수 – 주어진 배열에서 i~j 슬라이스를 자르고 정렬한 후 k번째 숫자를 찾는 문제입니다. 리스트 슬라이싱과 정렬을 다루는 좋은 연습이 됩니다. Level1 문제이지만 난이도는 높지 않으니 도전해보세요. (단, 라이브러리 사용이 자유로운 환경 가정)
2025.05.22 - [프로그래밍] - [PCCE] LV3 파이썬 완전정복: Part 1 PCCE 시험 개요와 LV3 등급 분석
2025.05.22 - [프로그래밍] - [PCCE] LV3 파이썬 완전정복: Part 2: 변수, 자료형, 연산자 – Python 기본 문법 ①
2025.05.23 - [프로그래밍] - [PCCE] LV3 파이썬 완전정복: Part 3 조건문 – 흐름 제어 기초
2025.05.24 - [프로그래밍] - [PCCE] LV3 파이썬 완전정복: Part 4 반복문 – while, for, 중첩 반복
'IT공부방' 카테고리의 다른 글
[PCCE] LV3 파이썬 완전정복: Part 7 문자열 처리 – 인덱싱, 슬라이싱, 포매팅 (0) | 2025.05.25 |
---|---|
[PCCE] LV3 파이썬 완전정복: Part 6 함수 정의와 활용, 표준 라이브러리 (math, random) (0) | 2025.05.25 |
[PCCE] LV3 파이썬 완전정복: Part 4 반복문 – while, for, 중첩 반복 (0) | 2025.05.24 |
[PCCE] LV3 파이썬 완전정복: Part 3 조건문 – 흐름 제어 기초 (0) | 2025.05.23 |
[PCCE] LV3 파이썬 완전정복: Part 2: 변수, 자료형, 연산자 – Python 기본 문법 ① (0) | 2025.05.22 |