기본 콘텐츠로 건너뛰기

방송대 오픈소스기반데이터분석 2강: 파이썬 데이터 처리 표현과 컨텍스트 관리

오픈소스기반데이터분석 2강 - 데이터 분석을 위한 파이썬 프로그래밍 (1)


방송대 오픈소스기반데이터분석 2강: 파이썬 데이터 처리 표현과 컨텍스트 관리

데이터 분석 코드는 값을 계산하는 데서 끝나지 않는다. 필요한 구간을 정확히 선택하고, 변환 규칙을 읽기 쉽게 표현하고, 결과 문자열을 목적에 맞게 만들고, 사용한 파일을 안전하게 닫아야 한다. 이 글은 슬라이싱·컴프리헨션·문자열 포맷팅·with문을 하나의 처리 흐름으로 연결해 코드의 결과와 실패 지점을 스스로 추적하도록 돕는다.

데이터 처리 코드는 선택·변환·표현·정리로 읽는다

강의자료는 데이터 분석 현장에서 파이썬이 자주 사용된다는 조사 사례를 학습 배경으로 제시한다. 여기서 중요한 점은 파이썬 사용 자체보다 데이터 구조를 효과적으로 다루고 처리 과정을 간결하고 정확하게 표현하는 능력이다.

한 줄짜리 코드도 네 가지 질문으로 나누어 보면 오류를 찾기 쉬워진다.

처리 단계핵심 질문대표 문법주요 실패 지점
선택어느 원소를 어떤 간격으로 가져오는가?시퀀스 슬라이싱끝 인덱스를 포함한다고 착각한다.
변환각 원소에 무엇을 적용하고 무엇을 남기는가?리스트·딕셔너리 컴프리헨션표현식과 조건의 역할을 뒤섞는다.
표현값을 어떤 자리와 형식으로 출력하는가?%, str.format(), f-문자열인수 순서·개수 또는 형식 지정자를 틀린다.
정리사용이 끝난 리소스를 어떻게 해제하는가?with문예외가 발생해 close()에 도달하지 못한다.

판단 핵심: 코드가 짧다는 이유만으로 효율적이거나 읽기 쉬운 것은 아니다. 선택 범위, 변환 순서, 출력 형식, 자원 해제 시점을 다른 사람이 재현할 수 있을 때 간결한 표현이 학습 가치와 안정성을 갖는다.

슬라이싱은 시작·끝·간격을 인덱스 이동으로 해석한다

리스트 슬라이싱은 대상 리스트의 일부를 생성하거나 특정 구간을 수정할 때 사용한다. 기본 형식은 리스트[시작:끝:간격]이다. 가장 중요한 규칙은 시작 인덱스는 포함하고 끝 인덱스는 포함하지 않는다는 점이다.

numbers = [10, 20, 30, 40, 50, 60, 70]

subset = numbers[0:3]
print(subset)  # [10, 20, 30]

0번에서 시작해 3번에 도달하기 전에 멈추므로 0·1·2번 원소가 선택된다. numbers[:3]처럼 시작을 생략해도 같은 결과다.

음수 인덱스는 끝에서부터 위치를 센다

-1은 마지막 원소, -2는 끝에서 두 번째 원소다. 따라서 numbers[-3:]은 끝에서 세 번째 원소부터 마지막까지 선택해 [50, 60, 70]을 만든다. 끝을 생략했으므로 리스트의 끝까지 진행한다.

간격은 선택 후 건너뛰기가 아니라 이동 폭이다

every_other = numbers[::2]
reversed_numbers = numbers[::-1]

print(every_other)      # [10, 30, 50, 70]
print(reversed_numbers) # [70, 60, 50, 40, 30, 20, 10]

::2는 0번에서 시작해 인덱스를 2씩 증가시킨다. ::-1은 이동 방향이 반대이므로 끝에서 시작해 역순으로 진행한다. 간격을 단순히 “몇 개를 건너뛴다”라고 외우면 2일 때 한 칸을 건너뛴다는 표현과 혼동하기 쉽다. 현재 인덱스에 step을 더해 다음 인덱스로 간다고 이해하는 편이 안전하다.

새 구간에서는 인덱스 표를 먼저 그려 결과를 검산한다

학습을 위해 강의와 다른 자료 temps = [18, 21, 19, 24, 27, 23, 20]을 가정하자. temps[1:6:2]의 결과를 문법만 보고 짐작하지 말고 이동 과정을 적어 본다.

  1. 시작 인덱스 1의 값 21을 선택한다.
  2. 간격 2를 더해 인덱스 3의 값 24를 선택한다.
  3. 다시 2를 더해 인덱스 5의 값 23을 선택한다.
  4. 다음 인덱스는 7이며 끝 경계 6 이상이므로 멈춘다.

따라서 결과는 [21, 24, 23]이다. 끝 값 6은 선택 후보가 아니라 정지 경계다.

표현방문 인덱스결과판정 근거
temps[:3]0, 1, 2[18, 21, 19]끝 3 직전에 정지
temps[-3:]4, 5, 6[27, 23, 20]-3은 인덱스 4와 같은 위치
temps[1:6:2]1, 3, 5[21, 24, 23]1에서 시작해 2씩 증가
temps[::-1]6, 5, 4, 3, 2, 1, 0[20, 23, 27, 24, 19, 21, 18]음수 간격으로 역방향 이동

자가 점검: 슬라이스를 볼 때 시작·끝·간격의 기본값을 먼저 채우고, 실제로 방문하는 인덱스를 적는다. 값 목록을 바로 예상하는 것보다 끝 경계와 음수 방향 오류를 줄일 수 있다.

컴프리헨션은 반복·변환·선별을 한 문장에 배치한다

리스트 컴프리헨션은 리스트를 간결하게 생성하거나 조작한다. 기본 구조는 [표현식 for 변수 in 반복가능한 객체]이고, 조건이 필요하면 뒤에 if 조건을 붙인다. 반복 가능한 객체에는 리스트·튜플·딕셔너리·문자열·집합·range 객체 등이 있다.

아래 두 코드는 같은 결과를 만든다. 컴프리헨션을 읽을 때는 실제 실행 순서인 반복 대상을 하나 꺼냄 → 조건을 검사함 → 표현식을 계산해 결과에 넣음의 순서로 펼친다.

numbers = []
for i in range(5):
    numbers.append(i)

same_numbers = [i for i in range(5)]

print(numbers)       # [0, 1, 2, 3, 4]
print(same_numbers)  # [0, 1, 2, 3, 4]

표현식은 값을 바꾸고 조건은 남길 원소를 고른다

scores = [52, 68, 77, 84, 91]
adjusted = [score + 3 for score in scores if score < 80]

print(adjusted)  # [55, 71, 80]

이 직접 구성 예에서는 먼저 각 점수가 80 미만인지 검사한다. 52·68·77만 통과하고, 통과한 값에 3을 더해 결과에 넣는다. 84와 91은 변환된 뒤 제거되는 것이 아니라 조건에서 먼저 탈락한다. 출력이 [55, 71, 80]인 이유를 이 순서로 재현할 수 있어야 한다.

오개념 교정: 컴프리헨션의 맨 앞 표현식이 반복 시작점이라고 생각하면 실행 순서를 틀리기 쉽다. 문법 표기는 표현식이 앞에 있지만, 의미를 추적할 때는 for → if → 표현식 순으로 읽는다.

딕셔너리 컴프리헨션은 결과마다 키와 값을 함께 만든다

딕셔너리 컴프리헨션은 대괄호 대신 중괄호를 사용하며 결과 표현식이 키: 값의 쌍이다. 새 딕셔너리를 생성할 때는 {키: 값표현식 for 변수 in 반복가능한 객체} 형태를 사용한다.

squares = {}
for i in range(5):
    squares[i] = i ** 2

same_squares = {i: i ** 2 for i in range(5)}

print(same_squares)  # {0: 0, 1: 1, 2: 4, 3: 9, 4: 16}

기존 딕셔너리를 바탕으로 만들 때는 dictionary.items()에서 키와 값을 함께 꺼낼 수 있다.

prices = {"pen": 1200, "note": 2500, "folder": 1800}
expensive = {name: price for name, price in prices.items()
             if price >= 1800}

print(expensive)  # {'note': 2500, 'folder': 1800}

리스트 컴프리헨션과의 결정적 차이는 입력 자료가 아니라 출력 구조다. 리스트 결과는 원소 하나씩 만들고, 딕셔너리 결과는 각 반복에서 키와 값을 함께 만든다.

문자열 포맷팅은 값과 표시 규칙을 연결한다

데이터 분석에서는 변수 값을 설명 문장에 넣거나 소수점 자릿수·천 단위 구분자·백분율처럼 일정한 표시 규칙을 적용한다. 파이썬 강의 범위에서는 C 스타일의 % 연산자, str.format(), f-문자열을 비교한다.

방식값을 놓는 방법적합한 상황주의점
C 스타일%s, %d 같은 지정자와 값 목록을 연결단순한 기존 코드나 C 스타일과의 일관성이 중요한 경우값이 많아지면 순서·개수 불일치가 눈에 잘 띄지 않는다.
str.format(){}에 위치·이름을 지정하고 뒤의 인자로 채움위치 재사용이나 키워드 인자를 명시하려는 경우복잡한 형식에서는 문자열과 인자 목록이 멀어져 장황해질 수 있다.
f-문자열문자열 안의 {표현식}을 직접 평가현재 변수와 계산식을 직관적으로 읽고 싶은 경우중괄호 안의 계산이 지나치게 길면 오히려 읽기 어려워진다.

C 스타일에서는 형식 지정자와 값의 타입을 맞춘다

주요 형식 지정자는 %d·%i 정수, %o 8진수, %x·%X 16진수, %f 실수, %.nf 소수점 이하 n자리, %c 단일 문자, %s 문자열, %% 퍼센트 기호 자체다.

item = "프린터"
price = 360000

print("상품명: %s, 가격: %d원" % (item, price))

지정자 순서와 뒤의 값 순서가 대응한다. 값이 많아질수록 순서를 바꾸거나 개수를 빠뜨리는 오류가 생기기 쉬운 이유다.

자리 표시자와 f-문자열은 같은 표시 규칙을 다르게 배치한다

str.format()은 중괄호 자리 표시자에 위치 인덱스나 키워드 이름을 적을 수 있다. 정렬·패딩·소수점 자릿수·천 단위 구분자 같은 형식도 지정할 수 있다.

name = "김하늘"
salary = 3600000
tax_rate = 0.08
net_income = int(salary * (1 - tax_rate))

message = "직원 {employee}, 월급 {income:,}원, 세금 {tax:.1%}, 실수령액 {net:,}원".format(
    employee=name,
    income=salary,
    tax=tax_rate,
    net=net_income
)

print(message)

계산은 3,600,000 × (1 - 0.08) = 3,312,000이다. :,는 천 단위 구분자를 넣고 :.1%는 0.08을 8.0%로 표시한다.

같은 결과를 f-문자열로 표현하면 변수와 표시 위치가 가까워진다. f-문자열은 파이썬 3.6부터 도입되었고 문자열 앞에 f 또는 F를 붙인다.

message = (
    f"직원 {name}, 월급 {salary:,}원, "
    f"세금 {tax_rate:.1%}, 실수령액 {net_income:,}원"
)

print(message)

포맷팅 방식을 고를 때 “가장 최신인가”만 보지 않는다. 기존 코드와의 일관성, 값과 자리의 대응을 얼마나 쉽게 확인할 수 있는지, 중괄호 안의 표현식이 지나치게 복잡하지 않은지를 함께 판단한다.

with문은 리소스 획득과 해제를 한 범위로 묶는다

파일·데이터베이스 연결·네트워크 소켓 같은 리소스는 획득해 사용한 뒤 폐기해야 한다. 직접 open()하고 마지막에 close()하는 코드는 정상 경로에서는 동작하지만, 쓰기 도중 예외가 발생하면 close()까지 실행되지 않을 수 있다.

file = open("output.txt", "w")
file.write("Hello, world!\n")
file.close()

컨텍스트 관리는 리소스를 효율적이고 안전하게 사용하도록 획득과 해제를 관리하는 메커니즘이다. with 키워드로 리소스를 사용하는 범위를 표시하면 범위를 벗어날 때 해제가 처리된다.

with open("output.txt", "w") as file:
    file.write("Hello, world!\n")
  1. open()으로 파일 리소스를 획득한다.
  2. as file로 범위 안에서 사용할 이름을 정한다.
  3. 들여쓴 블록에서 파일을 사용한다.
  4. 블록이 끝나면 정상 종료든 예외 발생이든 리소스 해제 절차가 수행된다.

실패 원인과 교정: close()를 적었다는 사실만 확인하지 말고, 그 줄에 도달하기 전에 실패할 수 있는지 본다. 실패 가능성이 있다면 리소스의 사용 범위를 with 블록으로 묶어 해제 책임을 컨텍스트 관리에 맡긴다.

핵심 개념 정리

  • 슬라이스는 시작을 포함하고 끝을 제외하며, 간격은 다음 인덱스로 이동하는 폭이다.
  • 컴프리헨션은 문법상 표현식이 앞에 있지만 결과 추적은 반복·조건·표현식 순으로 한다.
  • 리스트 컴프리헨션은 원소를, 딕셔너리 컴프리헨션은 키-값 쌍을 결과로 만든다.
  • 문자열 포맷팅은 값의 위치뿐 아니라 정수·실수·백분율·천 단위 같은 표시 규칙을 결정한다.
  • C 스타일·str.format()·f-문자열은 값과 자리의 연결 방식이 다르므로 코드 맥락과 가독성으로 선택한다.
  • with문은 리소스 사용 범위와 해제 시점을 결합해 예외 경로에서도 정리 가능성을 높인다.

데이터 처리 코드를 만나면 먼저 슬라이스의 실제 방문 인덱스를 적고, 컴프리헨션을 반복·조건·변환으로 펼친다. 이어서 출력값의 타입과 표시 규칙이 맞는지 확인하고, 마지막으로 리소스 사용 코드의 모든 종료 경로에서 해제가 가능한지 점검한다. 이 순서를 적용하면 짧은 파이썬 문법을 단순 암기하지 않고 결과와 오류를 재현 가능한 처리 과정으로 읽을 수 있다.

예상문제 10선

1. numbers = [10, 20, 30, 40, 50, 60, 70]일 때 numbers[1:6:2]의 결과는?

정답입니다.

오답입니다. 답안을 다시 선택해 보세요.

정답 및 해설 보기

정답: ③

  • ① 오답: 시작을 0으로 적용한 결과다. 이 슬라이스의 시작 인덱스는 1이다.
  • ② 오답: 끝 인덱스 6은 제외되므로 인덱스 6의 값 70은 포함되지 않는다.
  • ③ 정답: 인덱스 1, 3, 5를 방문하므로 20, 40, 60이 선택된다.
  • ④ 오답: 간격 2를 적용하지 않고 연속 구간으로 해석한 결과다.

2. 리스트 슬라이싱의 끝 인덱스에 대한 설명으로 옳은 것은?

정답입니다.

오답입니다. 답안을 다시 선택해 보세요.

정답 및 해설 보기

정답: ①

  • ① 정답: 슬라이스는 시작 포함, 끝 제외 규칙을 적용하므로 끝은 정지 경계다.
  • ② 오답: 끝 인덱스의 원소를 포함하지 않으며 그 뒤로 진행하지도 않는다.
  • ③ 오답: 양수와 음수 인덱스 모두 끝 경계 제외 원칙을 따른다.
  • ④ 오답: 간격의 생략 여부는 끝 인덱스 포함 여부를 바꾸지 않는다.

3. scores = [52, 68, 77, 84, 91]에서 [score + 3 for score in scores if score < 80]의 결과는?

정답입니다.

오답입니다. 답안을 다시 선택해 보세요.

정답 및 해설 보기

정답: ④

  • ① 오답: 조건을 통과한 원래 값만 적고 앞의 score + 3 변환을 누락했다.
  • ② 오답: 모든 원소를 변환해 조건에 탈락해야 할 84와 91까지 포함했다.
  • ③ 오답: 조건 방향을 반대로 해석했으며 변환식도 적용하지 않았다.
  • ④ 정답: 80 미만인 52, 68, 77만 남긴 뒤 각각 3을 더한다.

4. 리스트 컴프리헨션과 딕셔너리 컴프리헨션의 결정적 차이를 가장 잘 설명한 것은?

정답입니다.

오답입니다. 답안을 다시 선택해 보세요.

정답 및 해설 보기

정답: ②

  • ① 오답: 딕셔너리 컴프리헨션에도 조건을 붙여 결과 쌍을 선별할 수 있다.
  • ② 정답: 출력 구조가 단일 원소인지 키-값 쌍인지가 두 문법을 가르는 핵심이다.
  • ③ 오답: 두 방식 모두 다양한 반복 가능한 객체를 입력으로 사용할 수 있다.
  • ④ 오답: 괄호가 반대다. 리스트는 대괄호, 딕셔너리는 중괄호를 쓴다.

5. C 스타일 포맷팅보다 f-문자열이 적합한 상황으로 가장 타당한 것은?

정답입니다.

오답입니다. 답안을 다시 선택해 보세요.

정답 및 해설 보기

정답: ④

  • ① 오답: f-문자열의 장점은 변수와 표현식을 문자열 안에서 드러내는 데 있다.
  • ② 오답: 기존 C 스타일의 일관성이 우선이면 % 포맷팅을 유지할 근거가 된다.
  • ③ 오답: 순서 불일치는 장점이 아니라 C 스타일에서 발생하기 쉬운 오류다.
  • ④ 정답: f-문자열은 값과 출력 위치가 가까워 간단한 표현을 직관적으로 읽을 수 있다.

6. salary=3600000, tax_rate=0.08일 때 f"{int(salary * (1-tax_rate)):,}"의 결과는?

정답입니다.

오답입니다. 답안을 다시 선택해 보세요.

정답 및 해설 보기

정답: ①

  • ① 정답: 3,600,000에 0.92를 곱한 3,312,000을 정수로 만들고 천 단위 구분자를 넣는다.
  • ② 오답: 세율을 차감하지 않은 원래 급여만 표시한 결과다.
  • ③ 오답: 이는 3,600,000의 8%인 세금액이며 실수령액이 아니다.
  • ④ 오답: :,는 천 단위 구분자이지 백분율 형식이 아니다.

7. C 스타일 포맷팅의 형식 지정자 연결로 옳은 것은?

정답입니다.

오답입니다. 답안을 다시 선택해 보세요.

정답 및 해설 보기

정답: ③

  • ① 오답: %s는 문자열이고 실수는 %f 또는 자릿수를 붙인 %.nf를 사용한다.
  • ② 오답: %x는 소문자 16진수이며 대문자는 %X다.
  • ③ 정답: 포맷 문자열에서 퍼센트 기호 자체를 출력할 때 %%를 쓴다.
  • ④ 오답: %o는 8진수이고 10진 정수에는 %d 또는 %i를 쓴다.

8. with open(...) as file: 블록의 처리 흐름으로 가장 적절한 것은?

정답입니다.

오답입니다. 답안을 다시 선택해 보세요.

정답 및 해설 보기

정답: ②

  • ① 오답: 리소스를 획득하기 전에 파일을 사용할 수 없으므로 순서가 뒤집혔다.
  • ② 정답: open으로 획득하고 as 이름으로 블록에서 사용한 뒤 범위 종료 시 해제한다.
  • ③ 오답: 해제는 사용을 마친 뒤의 단계이며 시작 전에 수행하지 않는다.
  • ④ 오답: close()를 먼저 호출하면 블록에서 파일을 쓸 수 없고 with문의 흐름과도 다르다.

9. open() 뒤 마지막 줄에 close()를 적었으므로 리소스가 안전하다는 판단이 불완전한 이유는?

정답입니다.

오답입니다. 답안을 다시 선택해 보세요.

정답 및 해설 보기

정답: ①

  • ① 정답: 정상 경로뿐 아니라 예외 경로도 확인해야 하며 with문은 해제 책임을 범위와 묶는다.
  • ② 오답: close()는 획득한 파일의 사용을 마친 뒤 호출하는 연산이다.
  • ③ 오답: with문은 리소스 컨텍스트를 관리하며 문자열 포맷팅을 수행하지 않는다.
  • ④ 오답: 사용을 마친 리소스를 해제하지 않으면 누수나 데이터 손상 위험이 커질 수 있다.

10. 온도 목록에서 최근 세 값을 골라 섭씨 기호가 포함된 문장으로 파일에 안전하게 저장하려 한다. 적절한 구성은?

정답입니다.

오답입니다. 답안을 다시 선택해 보세요.

정답 및 해설 보기

정답: ④

  • ① 오답: %d 하나는 목록 전체와 맞지 않고 open()만으로는 해제 경로가 마련되지 않는다.
  • ② 오답: [::2]는 간격 2의 원소를 고르며 최근 세 값 선택이 아니고, 먼저 닫으면 쓸 수 없다.
  • ③ 오답: 컴프리헨션은 데이터 구조를 만들고 f-문자열은 문자열을 만들며 리소스 획득·해제 역할을 하지 않는다.
  • ④ 정답: 선택·표현·리소스 관리의 각 목적에 맞는 문법을 올바른 순서로 결합했다.

참고 자료와 작성 기준

이 글은 해당 차시 강의자료를 바탕으로 학습 목적에 맞게 재구성한 비공식 학습자료입니다. 코드 실행 과정, 직접 구성한 예제와 문제 해설은 학습자의 이해를 돕도록 구성하고 검토했습니다.

  • 작성·편집: 올에이클래스 학습연구팀
  • 주요 근거: 한국방송통신대학교 컴퓨터과학과 「오픈소스기반데이터분석」 2강 ‘데이터 분석을 위한 파이썬 프로그래밍 1’ 강의록
  • 보충 자료: 별도 외부 자료를 사용하지 않음
  • 편집 원칙: 올에이클래스 편집 정책
  • 최종 내용 검토: 2026-08-30

댓글