실기 공부방READ · TRACE · RECALL

정보처리 실무 · 학습 노트

Python

슬라이싱·공유 객체·반복을 정확하게

Python 3 기준이다. 문법은 짧지만 얕은 복사와 인덱스 때문에 틀리기 쉽다. 들여쓰기로 실행 범위를 확인한 뒤 리스트가 공유되는지 먼저 그리자.

기초부터 실전까지

처음 배우는 분의 학습 순서

기호와 용어가 낯설면 기초·상세 보강을 먼저 읽고, 기존 핵심 정리로 연결하세요. 예제의 값을 손으로 계산한 뒤 확인 질문을 답하고 마지막에 문제를 풉니다.

추가된 상세 학습 13개 펼쳐보기
이 단원 목차 21개
이번 단원 완료 기준

핵심 규칙을 설명하고, 연습문제의 답과 이유를 해설 없이 적을 수 있으면 체크하세요. 이해 체크와 정답 기록은 별도로 저장됩니다.

01

기본 문법과 출력

블록은 중괄호 대신 들여쓰기로 구분한다. 변수 선언 키워드는 없으며 실행 중 객체에 이름을 연결한다. print(a,b)는 기본적으로 공백으로 구분하고 마지막에 줄바꿈한다.

답을 가리고 확인

“기본 문법과 출력”의 핵심 규칙과 헷갈리는 지점을 설명해 보세요.

확인 답안 보기

True, False, None의 대소문자를 지킨다. len(a), type(a), int("12"), str(12)를 읽을 수 있어야 한다. input()의 결과는 문자열이다. 숫자로 계산하려면 변환이 필요하다.

꼭 기억할 것

True, False, None의 대소문자를 지킨다. len(a), type(a), int("12"), str(12)를 읽을 수 있어야 한다.

헷갈리는 지점 input()의 결과는 문자열이다. 숫자로 계산하려면 변환이 필요하다.

02

range와 슬라이싱

range(start,stop,step)과 a[start:stop:step]은 stop을 포함하지 않는다. a[-1]은 마지막 원소다. a[::-1]은 역순 복사다. 음수 step이면 인덱스가 줄어든다.

과정으로 이해하기

  1. range(1,6,2)는 1,3,5를 만든다. 끝 6은 제외.
  2. "ABCDE"[1:4]는 인덱스1,2,3의 BCD.
  3. 음수 step에서는 이동 방향을 먼저 화살표로 적는다.

답을 가리고 확인

"ABCDE"[::-2]는?

확인 답안 보기

ECA. 위치4,2,0.

꼭 기억할 것

range(5,0,-2)는 5,3,1. "ABCDE"[1:5:2]는 "BD".

헷갈리는 지점 역방향 슬라이스에서 생략한 stop과 명시적 -1은 다르다. 문자열[4:-1:-1]은 빈 문자열이다.

03

리스트·튜플·집합·딕셔너리

list는 순서 있고 변경 가능, tuple은 순서 있고 원소 대입 불가, set은 중복 제거 집합, dict는 key→value 매핑이다. 빈 집합은 set(), {}는 빈 dict다.

답을 가리고 확인

“리스트·튜플·집합·딕셔너리”의 핵심 규칙과 헷갈리는 지점을 설명해 보세요.

확인 답안 보기

a.append(x)는 한 원소, a.extend(xs)는 여러 원소를 추가한다. dict.items()는 키와 값의 쌍이다. 집합의 표시 순서를 정답으로 가정하지 않는다. 정렬 결과를 물으려면 sorted(set)을 쓴다.

꼭 기억할 것

a.append(x)는 한 원소, a.extend(xs)는 여러 원소를 추가한다. dict.items()는 키와 값의 쌍이다.

헷갈리는 지점 집합의 표시 순서를 정답으로 가정하지 않는다. 정렬 결과를 물으려면 sorted(set)을 쓴다.

04

별칭과 얕은 복사

b=a는 같은 리스트를 가리킨다. b=a[:] 또는 a.copy()는 바깥 리스트만 새로 만든다. 안쪽 리스트는 계속 공유할 수 있다.

답을 가리고 확인

“별칭과 얕은 복사”의 핵심 규칙과 헷갈리는 지점을 설명해 보세요.

확인 답안 보기

[[0]*2]*3은 동일한 내부 리스트를 세 번 참조한다. 독립 행은 [[0]*2 for _ in range(3)]. 복사한 바깥 리스트에 append하는 것과 내부 원소를 바꾸는 것을 구분한다.

꼭 기억할 것

[[0]*2]*3은 동일한 내부 리스트를 세 번 참조한다. 독립 행은 [[0]*2 for _ in range(3)].

헷갈리는 지점 복사한 바깥 리스트에 append하는 것과 내부 원소를 바꾸는 것을 구분한다.

05

컴프리헨션과 함수

[식 for 원소 in 반복가능객체 if 조건]은 조건을 통과한 원소만 식으로 바꾼다. 함수는 def로 정의하며 return이 없으면 None이다.

답을 가리고 확인

“컴프리헨션과 함수”의 핵심 규칙과 헷갈리는 지점을 설명해 보세요.

확인 답안 보기

[x*x for x in range(5) if x%2] → [1,9]. 함수의 기본 인자에 []를 쓰면 함수 정의 때 만들어진 리스트가 호출 사이 공유된다.

꼭 기억할 것

[x*x for x in range(5) if x%2] → [1,9].

헷갈리는 지점 함수의 기본 인자에 []를 쓰면 함수 정의 때 만들어진 리스트가 호출 사이 공유된다.

06

문자열과 딕셔너리 순회

split은 나누고 join은 구분자로 잇는다. 문자열은 불변이라 replace나 upper 결과를 사용해야 한다. Python 3.7 이상 dict는 삽입 순서를 유지한다.

답을 가리고 확인

“문자열과 딕셔너리 순회”의 핵심 규칙과 헷갈리는 지점을 설명해 보세요.

확인 답안 보기

for k in d는 키 순회. k[-1]은 키 문자열의 마지막 문자이고 d[k][0]은 값의 첫 원소다. 기존 키의 값을 갱신해도 그 키의 삽입 위치는 바뀌지 않는다. 없는 키의 d[k]는 KeyError, d.get(k,기본값)은 기본값.

꼭 기억할 것

for k in d는 키 순회. k[-1]은 키 문자열의 마지막 문자이고 d[k][0]은 값의 첫 원소다.

헷갈리는 지점 기존 키의 값을 갱신해도 그 키의 삽입 위치는 바뀌지 않는다. 없는 키의 d[k]는 KeyError, d.get(k,기본값)은 기본값.

07

논리·정렬·나눗셈

and/or는 항상 bool을 반환하지 않고 평가한 피연산자를 반환할 수 있다. ==는 값 동등성, is는 객체 동일성이다. sorted(a)는 새 리스트, a.sort()는 원본 정렬 후 None을 반환한다.

답을 가리고 확인

“논리·정렬·나눗셈”의 핵심 규칙과 헷갈리는 지점을 설명해 보세요.

확인 답안 보기

빈 문자열·빈 컨테이너·0·None은 거짓 취급. //는 floor, %는 나눗셈 항등식을 만족한다. 문자열이나 숫자의 값 비교에 is를 쓰지 않는다. 객체 재사용 여부에 따라 우연히 맞는 사례를 외우지 않는다.

꼭 기억할 것

빈 문자열·빈 컨테이너·0·None은 거짓 취급. //는 floor, %는 나눗셈 항등식을 만족한다.

헷갈리는 지점 문자열이나 숫자의 값 비교에 is를 쓰지 않는다. 객체 재사용 여부에 따라 우연히 맞는 사례를 외우지 않는다.

08

언패킹과 다중 대입

a,b=b,a처럼 콤마로 나열한 다중 대입은 오른쪽 값을 모두 먼저 평가해 튜플로 만든 뒤 왼쪽에 순서대로 대입하므로 임시 변수 없이 값을 교환할 수 있다. a,*b,c=리스트처럼 *가 붙은 이름은 나머지 원소를 리스트로 묶어 받는다.

답을 가리고 확인

“언패킹과 다중 대입”의 핵심 규칙과 헷갈리는 지점을 설명해 보세요.

확인 답안 보기

언패킹 대상 개수와 오른쪽 값 개수가 맞아야 한다. * 붙은 이름은 하나만 쓸 수 있다. a,b=b,a는 왼쪽부터 하나씩 즉시 대입하는 것이 아니라 오른쪽을 통째로 평가한 뒤 대입한다. 중간 값이 이미 바뀐 것처럼 순서를 착각하지 않는다.

꼭 기억할 것

언패킹 대상 개수와 오른쪽 값 개수가 맞아야 한다. * 붙은 이름은 하나만 쓸 수 있다.

헷갈리는 지점 a,b=b,a는 왼쪽부터 하나씩 즉시 대입하는 것이 아니라 오른쪽을 통째로 평가한 뒤 대입한다. 중간 값이 이미 바뀐 것처럼 순서를 착각하지 않는다.

09

/ · // · % · ** : 기호부터 이해하기

연산자는 계산 방법을 지정하는 기호다. /는 나눗셈, //는 나눈 값을 바닥값으로 내리는 나눗셈, %는 나머지, **는 거듭제곱이다. 7개를 2개씩 묶으면 완전한 묶음은 3개, 남은 것은 1개다. 따라서 7 // 2는 3이고 7 % 2는 1이다.

음수에서는 “소수점만 지운다”는 설명이 틀린다. -7 / 3은 약 -2.333이고, 이 값 이하의 가장 큰 정수는 -3이다. 그래서 -7 // 3은 -3이다. a = (a // b) * b + (a % b)로 검산하면 -7 = -3 * 3 + 2다. 나누는 수가 0이면 예외가 난다.

print(7 / 2, 7 // 2, 7 % 2, 2 ** 3)
print(-7 // 3, -7 % 3)
print(7.0 // 2)
/ · // · % · ** : 기호부터 이해하기 · 한눈에 비교
기호뜻예활용
/일반 나눗셈9 / 2 → 4.5평균
//바닥 나눗셈9 // 2 → 4몫·중간 인덱스
%나머지9 % 2 → 1홀짝·순환
**거듭제곱3 ** 2 → 9제곱
^비트 XOR3 ^ 2 → 1비트 비교

과정으로 이해하기

  1. 첫 줄: 3.5 3 1 8. 각각 나눗셈·바닥 나눗셈·나머지·2의 3제곱이다.
  2. 둘째 줄: -3 2. 음수 몫은 아래로 내리고, 나머지는 등식으로 확인한다.
  3. 셋째 줄: 3.0. //의 수학적 결과와 결과 객체의 자료형을 나누어 생각한다.

답을 가리고 확인

-8 // 3과 -8 % 3은?

확인 답안 보기

-3과 1. -8 = (-3) × 3 + 1.

꼭 기억할 것

몫 //, 나머지 %, 제곱 **. 7 / 2 = 3.5, 7 // 2 = 3, 7 % 2 = 1.

헷갈리는 지점 Python의 //는 주석이 아니다. 주석은 #이다. 실수가 포함된 7.0 // 2는 정수 객체 3이 아니라 float 3.0이다.

10

대입·자료형·변환과 입력

x = 3은 x라는 이름을 값 3에 연결하는 대입이다. x == 3은 같은 값인지 비교해서 True 또는 False를 만드는 식이다. int는 정수, float는 실수, str은 문자열, bool은 논릿값, None은 값이 없음을 나타내는 특별한 객체다.

input()의 결과는 항상 문자열이다. 숫자 계산을 하려면 int(input())처럼 변환한다. "2" + "3"은 "23", int("2") + int("3")은 5다. int(3.9)는 3이고 int(-3.9)는 -3으로 0 방향으로 잘린다.

a, b = "2", "3"
print(a + b, int(a) + int(b))
x, y = 1, 2
x, y = y, x
print(x, y)

과정으로 이해하기

  1. 출력은 23 5, 다음 줄 2 1. 동시 대입은 오른쪽 값을 먼저 계산한다.

답을 가리고 확인

x = 5 뒤 x += 2는 무슨 뜻인가?

확인 답안 보기

x = x + 2와 같은 값을 만든다. x는 7.

꼭 기억할 것

= 대입 / == 값 비교 / int("12") 숫자 변환 / str(12) 문자열 변환.

헷갈리는 지점 문자열 "3"과 정수 3을 +로 바로 더하면 TypeError. int("3.5")는 ValueError이며 int(float("3.5"))와 구별한다.

11

들여쓰기·조건문·조건식

if 뒤 조건이 참이면 콜론 다음의 들여쓴 블록을 실행한다. elif는 앞 조건이 거짓일 때 다음 조건을 검사하며 else는 모두 거짓일 때 실행한다. 같은 if-elif-else 묶음에서는 선택된 한 블록만 실행한다.

0, 0.0, 빈 문자열, 빈 리스트·튜플·집합·딕셔너리, None은 거짓으로 취급된다. "0"은 비어 있지 않은 문자열이므로 참이다. a < x < b는 범위 비교이고 값1 if 조건 else 값2는 결과값을 고르는 조건식이다.

x = 0
if x:
    print("A")
elif "0":
    print("B")
else:
    print("C")
print("짝" if x % 2 == 0 else "홀")

과정으로 이해하기

  1. 0은 거짓이므로 첫 블록을 건너뛴다. "0"은 참이어서 B를 출력한다.
  2. 0의 나머지는 0이므로 다음 줄은 짝.

답을 가리고 확인

bool([]), bool([0]), bool("False")는?

확인 답안 보기

False, True, True. 원소나 글자가 있으면 참이다.

꼭 기억할 것

블록은 들여쓰기로 결정된다. ==, !=, <, <=, >, >=는 비교 연산자.

헷갈리는 지점 if를 두 번 독립해서 쓰면 둘 다 실행될 수 있다. elif 두 개와 동작이 다르다.

12

and · or · not과 단락 평가

not은 참·거짓을 뒤집는다. and는 왼쪽이 거짓이면 그 값을 반환하고, 참이면 오른쪽을 평가해 반환한다. or는 왼쪽이 참이면 그 값을 반환하고, 거짓이면 오른쪽을 평가해 반환한다. 따라서 and와 or의 결과가 반드시 bool인 것은 아니다.

우선순위는 비교가 not보다 먼저, 그 다음 and, 마지막 or다. a and b or c는 (a and b) or c로 읽는다. 결과가 이미 정해지면 뒤 함수가 호출되지 않을 수 있다.

print(0 or 7, 3 and 8, not [])
print(False and (1 / 0))

과정으로 이해하기

  1. 첫 줄 7 8 True. 둘째 줄 False: 왼쪽이 거짓이라 1/0을 실행하지 않는다.

답을 가리고 확인

[] or "기본값"의 결과는?

확인 답안 보기

기본값 문자열. 빈 리스트가 거짓이므로 오른쪽을 반환한다.

꼭 기억할 것

0 or 7 → 7 / 3 and 8 → 8 / not [] → True.

헷갈리는 지점 &와 |는 정수에서 비트 연산이다. and와 or로 읽지 않는다.

13

for·while·break·continue·반복 else

for x in 대상은 대상에서 원소를 하나씩 꺼내 x에 넣는다. while 조건은 조건이 참인 동안 반복한다. break는 가장 가까운 반복문 전체를 끝내며 continue는 현재 회차의 남은 부분을 건너뛴다.

반복문에 붙은 else는 break 없이 정상 종료했을 때 실행된다. 반복을 한 번도 하지 않아도 정상 종료라면 실행된다. 중첩 반복문의 break는 안쪽 반복문 하나만 끝낸다.

for i in range(1, 5):
    if i == 2:
        continue
    if i == 4:
        break
    print(i, end=" ")
else:
    print("완료")

과정으로 이해하기

  1. i=1 출력, i=2 건너뜀, i=3 출력, i=4 break. 출력은 끝 공백을 포함한 "1 3 ". 완료는 출력하지 않는다.

답을 가리고 확인

range(2, 7, 2)의 값들은?

확인 답안 보기

2, 4, 6. 7은 포함하지 않는다.

꼭 기억할 것

range(시작, 끝, 간격)의 끝은 포함하지 않는다. while은 종료 조건이 바뀌는지 확인한다.

헷갈리는 지점 for의 else는 if의 else와 다르다. break로 종료하면 실행되지 않는다.

14

인덱스와 슬라이스를 손으로 적기

인덱스는 한 원소의 위치다. 길이 5인 문자열 ABCDE의 인덱스는 0~4, 뒤에서 세는 인덱스는 -5~-1이다. a[-1]은 마지막 원소다. a[start:stop:step]은 여러 원소를 새 시퀀스로 가져오며 stop 위치는 제외한다.

양의 step은 오른쪽, 음의 step은 왼쪽으로 이동한다. 생략한 경계는 이동 방향에 맞는 시작·끝을 사용한다. [::-1]은 마지막부터 처음까지 역순이다. 명시적 -1은 실제 마지막 원소 위치로 해석하므로 [:-1:-1]과 [::-1]은 같지 않다.

s = "ABCDE"
print(s[-1], s[1:4], s[::2], s[::-1])

과정으로 이해하기

  1. 인덱스를 0 A, 1 B, 2 C, 3 D, 4 E로 적는다.
  2. 각 선택 위치는 4 / 1,2,3 / 0,2,4 / 4,3,2,1,0. 출력 E BCD ACE EDCBA.

답을 가리고 확인

"ABCDE"[1:5:2]는?

확인 답안 보기

BD. 위치 1,3만 가져온다.

꼭 기억할 것

ABCDE[1:4] → BCD / [::2] → ACE / [4:0:-2] → EC.

헷갈리는 지점 범위를 벗어난 단일 인덱스는 IndexError, 슬라이스 경계는 조정된다. step=0은 ValueError.

15

리스트 메서드·삭제·반환값

append(x)는 x 하나를 끝에 넣고 extend(대상)는 대상의 원소들을 각각 넣는다. insert(i,x)는 i 위치에 삽입한다. remove(x)는 처음 만나는 값 x를 삭제하고 pop(i)는 i 위치 값을 꺼내 반환하며 삭제한다. pop()은 마지막 값을 꺼낸다.

리스트의 sort(), reverse(), append() 등은 원본을 바꾸고 None을 반환한다. sorted(a)는 새 정렬 리스트를 반환하며 원본을 유지한다. del a[i]는 반환값 없이 삭제하는 문장이다.

a = [1]
a.append([2, 3])
a.extend([4, 5])
x = a.pop()
print(a, x)

과정으로 이해하기

  1. append 뒤 [1,[2,3]], extend 뒤 [1,[2,3],4,5], pop 뒤 [1,[2,3],4]와 반환값 5.

답을 가리고 확인

a=[3,1]; b=sorted(a)의 a와 b는?

확인 답안 보기

a는 [3,1], b는 [1,3].

꼭 기억할 것

append([2,3]) → 중첩 리스트 한 개 추가 / extend([2,3]) → 원소 두 개 추가.

헷갈리는 지점 remove는 인덱스가 아니라 값을 받는다. 없는 값을 remove하면 ValueError.

16

딕셔너리·집합·튜플의 함정

딕셔너리는 키를 값에 대응시키며 같은 키에 다시 대입하면 값을 덮어쓴다. d[k]는 키가 없으면 KeyError, d.get(k,기본값)는 기본값을 반환한다. for k in d는 키, d.items()는 키·값 쌍을 순회한다. 집합은 중복을 없애고 수학적 집합 연산을 지원한다.

튜플은 원소를 다른 값으로 재대입할 수 없는 시퀀스다. 원소 하나짜리 튜플은 (1,)처럼 쉼표가 필요하다. 튜플 안에 리스트가 있으면 그 리스트 자체는 변경할 수 있다. 빈 {}는 딕셔너리, 빈 집합은 set()이다.

d = {"a": 1, "b": 2}
d["a"] = 9
print(d.get("c", 0), "a" in d)
print(sorted({1, 2} ^ {2, 3}))

과정으로 이해하기

  1. 첫 줄 0 True. 둘째 줄 [1, 3]: 둘 중 한 집합에만 있는 값들.

답을 가리고 확인

(3)과 (3,)의 차이는?

확인 답안 보기

(3)은 정수 3, (3,)는 원소 한 개짜리 튜플.

꼭 기억할 것

in은 딕셔너리에서 키 포함 검사. 집합 & 교집합, | 합집합, - 차집합, ^ 대칭차.

헷갈리는 지점 집합 출력·순회 순서를 고정 답으로 암기하지 않는다. 순서가 필요하면 sorted를 쓴다.

17

함수·return·지역 이름·lambda

def는 함수를 정의한다. 매개변수는 호출할 때 인자를 받아 사용하는 이름이다. return은 함수 실행을 끝내고 값을 호출 위치로 돌려준다. print는 화면 출력이며 반환과 다르다. return이 없거나 return만 쓰면 반환값은 None이다.

함수 안에서 대입한 이름은 일반적으로 지역 이름이다. global은 모듈 수준 이름에 대입하겠다는 선언이다. lambda x: x*2는 짧은 함수를 만드는 식이며 별도 return을 쓰지 않는다. sorted(a,key=...)는 key 결과로 정렬하지만 원래 원소를 돌려준다.

def f(x):
    print(x + 1)

r = f(2)
print(r)
print(sorted(["bbb", "a", "cc"], key=lambda s: len(s)))

과정으로 이해하기

  1. f가 3을 출력하지만 반환값은 None. 다음 줄 None, 마지막 줄 ['a', 'cc', 'bbb'].

답을 가리고 확인

return a, b는 어떤 값을 반환하는가?

확인 답안 보기

두 값을 담은 튜플. 호출자가 x,y=f()로 풀어 받을 수 있다.

꼭 기억할 것

인자 → 매개변수 → 본문 → 반환값 → 호출자 순서로 추적한다.

헷갈리는 지점 함수에서 리스트를 수정하는 것과 매개변수 이름을 새 리스트로 재연결하는 것은 다르다.

18

문자열 split·join·replace와 출력 형식

split()은 공백 구간을 기준으로 문자열을 나눠 리스트로 만든다. split(",")는 쉼표를 구분자로 사용한다. "-".join(문자열목록)은 사이에 -를 넣어 합친다. replace(이전,새값)는 교체한 새 문자열을 반환한다.

print(a,b)는 기본 sep=" "로 값 사이에 공백을 넣고 end="\n"으로 줄을 끝낸다. sep와 end를 지정하면 답의 공백·줄바꿈도 달라진다. f"{x:.2f}"는 소수 둘째 자리까지 표시한다.

s = "a,b,c"
print("-".join(s.split(",")))
print(1, 2, sep=":", end="!")
print(3)

과정으로 이해하기

  1. 첫 줄 a-b-c. 다음 출력 1:2!3 뒤 줄바꿈: 두 번째 print가 줄을 바꾸지 않아 세 번째가 붙는다.

답을 가리고 확인

"banana".replace("a","o",1)은?

확인 답안 보기

bonana. 첫 번째 a만 바꾼다.

꼭 기억할 것

문자열은 불변이다. 변환 결과를 대입하지 않으면 원본 이름의 값은 그대로다.

헷갈리는 지점 join의 원소는 문자열이어야 한다. 정수 목록은 str 변환 후 합친다.

19

컴프리헨션·enumerate·zip·map

[식 for x in 대상 if 조건]은 원소를 꺼내 조건을 검사하고 통과한 원소에 식을 계산해 새 리스트를 만든다. enumerate는 (번호,원소), zip은 여러 대상의 같은 위치 원소들을 묶는다. 기본 zip은 가장 짧은 대상이 끝나면 종료한다.

map(함수,대상)은 각 원소에 함수를 적용하는 이터레이터다. list(map(int,["2","3"]))은 [2,3]이다. 이터레이터를 이미 소진하면 다시 순회할 때 값이 남아 있지 않을 수 있다.

print([i * j for i in [1, 2] for j in [3, 4]])
print(list(enumerate(["A", "B"], start=1)))
print(list(zip([1, 2, 3], ["a", "b"])))

과정으로 이해하기

  1. 첫 줄 [3, 4, 6, 8]. i=1에서 j=3,4를 모두 처리한 뒤 i=2로 간다.
  2. 둘째 줄 [(1, 'A'), (2, 'B')], 셋째 줄 [(1, 'a'), (2, 'b')].

답을 가리고 확인

[x for x in range(4) if x%2]는?

확인 답안 보기

[1,3]. 나머지 1은 참이고 0은 거짓.

꼭 기억할 것

중첩 컴프리헨션은 왼쪽 for가 바깥 반복, 오른쪽 for가 안쪽 반복.

헷갈리는 지점 [x if 조건 else y for ...]의 조건식과 [x for ... if 조건]의 필터는 다르다.

20

==·is·얕은 복사·깊은 복사

==는 값이 같은지, is는 같은 객체인지 검사한다. b=a는 새 리스트를 만들지 않고 같은 객체에 다른 이름을 연결한다. a.copy() 또는 a[:]는 새 바깥 리스트를 만들지만 내부 리스트는 여전히 공유하는 얕은 복사다.

copy.deepcopy(a)는 중첩된 변경 가능한 객체까지 복사할 때 쓴다. 종이에 바깥 리스트와 내부 리스트를 별도의 상자로 그리면 어느 변경이 공유되는지 보인다.

a = [[1], [2]]
b = a.copy()
b[0].append(9)
b.append([3])
print(a)
print(a is b, a[0] is b[0])

과정으로 이해하기

  1. a와 b는 서로 다른 바깥 상자지만 첫 내부 상자를 공유한다.
  2. 출력 [[1, 9], [2]], 다음 줄 False True.

답을 가리고 확인

a=[[0]*2 for _ in range(2)]가 [[0]*2]*2보다 안전한 이유는?

확인 답안 보기

각 반복에서 내부 리스트를 새로 만들어 행이 서로 다른 객체이기 때문이다.

꼭 기억할 것

바깥 리스트의 append와 내부 리스트의 append를 구별한다.

헷갈리는 지점 작은 정수·문자열의 객체 재사용에 기대 is로 값 비교를 하지 않는다.

21

기본 인자와 반복 리스트 공유

함수의 기본 인자 식은 함수 정의 시 평가된다. 기본 인자로 만든 가변 리스트는 호출 사이에 재사용될 수 있다. [[0]*2]*2는 내부 리스트 하나를 두 번 참조한다. 행마다 독립된 리스트가 필요하면 컴프리헨션으로 만든다.

def f(a=[]):
    a.append(1)
    return len(a)
print(f(), f())
a = [[0]*2]*2
a[0][1] = 7
print(a)

답을 가리고 확인

a=[[0]*2]*2; a[0][1]=7 이후 a는?

확인 답안 보기

[[0, 7], [0, 7]]. 두 행이 같은 내부 리스트를 가리킨다.

2026.10.14 재확인: Python 3.14 제어 흐름

꼭 기억할 것

기본 인자 []는 호출마다 새로 만들어지지 않는다. [[0]*2 for _ in range(2)]는 행이 독립적이다.

헷갈리는 지점 리스트의 바깥쪽만 복사해도 내부 객체 참조는 공유될 수 있다.

직접 풀어보기 24문제

모두 유형 연습을 위해 직접 만든 문제입니다. C 예제의 printf·strlen은 필요한 표준 헤더가 포함된 상황을 가정합니다. Java는 표시된 클래스·main 위치에서 실행합니다. 단답은 동의어가 있을 수 있어 자동 판정 대신 자기 채점을 사용합니다.

Python · 기본 · 창작 01미풀이

슬라이스

출력은?

s="ABCDE"
print(s[1:5:2])
정답과 풀이 확인

정답 BD

인덱스 1과 3을 선택한다. stop 5는 제외한다.

해설과 비교해 직접 채점
Python · 기본 · 창작 02미풀이

역순 간격

출력은?

print("ABCDEF"[::-2])
정답과 풀이 확인

정답 FDB

역순으로 인덱스 5,3,1을 선택한다.

해설과 비교해 직접 채점
Python · 기본 · 창작 03미풀이

range 합

출력은?

print(sum(range(6,0,-2)))
정답과 풀이 확인

정답 12

6,4,2를 더한다. stop 0은 포함하지 않는다.

해설과 비교해 직접 채점
Python · 기본 · 창작 04미풀이

별칭과 복사

출력은?

a=[1,2]
b=a
c=a[:]
b[0]=7
c.append(3)
print(a,c)
정답과 풀이 확인

정답 [7, 2] [1, 2, 3]

b는 a와 같은 리스트라 a[0]도 바뀐다. c는 별도 바깥 리스트여서 append가 c만 바꾼다.

해설과 비교해 직접 채점
Python · 응용 · 창작 05미풀이

중첩 리스트

출력은?

a=[[0]*2]*2
a[0][0]=5
print(a)
정답과 풀이 확인

정답 [[5, 0], [5, 0]]

두 행이 동일한 내부 리스트를 참조한다. 한 행의 첫 원소를 바꾸면 양쪽에서 보인다.

해설과 비교해 직접 채점
Python · 기본 · 창작 06미풀이

컴프리헨션

출력은?

print([x*x for x in range(6) if x%2==1])
정답과 풀이 확인

정답 [1, 9, 25]

range(6)은 0부터 5. 홀수 1,3,5를 제곱한다.

해설과 비교해 직접 채점
Python · 응용 · 창작 07미풀이

딕셔너리 인덱스

출력은?

d={"cat":[3,4],"sun":[7,8]}
for k,v in d.items():
    print(k[-1]+str(v[0]),end="")
정답과 풀이 확인

정답 t3n7

cat의 끝 t와 값 첫 원소 3, sun의 끝 n과 값 첫 원소 7을 삽입 순서로 출력한다.

해설과 비교해 직접 채점
Python · 응용 · 창작 08미풀이

기본 인자 공유

출력은?

def f(x, a=[]):
    a.append(x)
    return a
print(f(2))
print(f(5))
정답과 풀이 확인

정답 [2]
[2, 5]

기본 리스트는 함수 정의 때 한 번 생성된다. 첫 호출에서 2, 다음 호출에서 같은 리스트에 5를 추가한다.

해설과 비교해 직접 채점
Python · 기본 · 창작 09미풀이

음수 나눗셈

출력은?

print(-7//3,-7%3)
정답과 풀이 확인

정답 -3 2

-7/3을 아래 정수로 내리면 -3. -7=(-3)*3+2이므로 나머지 2.

해설과 비교해 직접 채점
Python · 기본 · 창작 10미풀이

집합 연산

출력은?

a={1,2,4}; b={2,3,4}
print(sorted(a & b))
정답과 풀이 확인

정답 [2, 4]

교집합은 2,4이며 sorted로 순서를 고정해 리스트로 만든다.

해설과 비교해 직접 채점
Python · 기본 · 창작 11미풀이

불변 문자열

출력은?

a="web"
b=a.upper()
print(a,b)
정답과 풀이 확인

정답 web WEB

upper()는 새로운 문자열을 반환하며 a 자체는 바꾸지 않는다.

해설과 비교해 직접 채점
Python · 기본 · 창작 12미풀이

정렬 반환

출력은?

a=[3,1,2]
b=a.sort()
print(a,b)
정답과 풀이 확인

정답 [1, 2, 3] None

sort는 원본 a를 정렬하고 반환값은 None이다.

해설과 비교해 직접 채점
Python · 기본 · 창작 13미풀이

값 교환

출력은?

a,b=1,2
a,b=b,a
print(a,b)
정답과 풀이 확인

정답 2 1

오른쪽 b,a를 먼저 평가해 (2,1)을 만든 뒤 a,b에 순서대로 대입한다.

해설과 비교해 직접 채점
Python · 기본 · 창작 14미풀이

별표 언패킹

출력은?

a,*b,c=[1,2,3,4,5]
print(a,b,c)
정답과 풀이 확인

정답 1 [2, 3, 4] 5

a는 첫 원소, c는 마지막 원소, *b는 가운데 나머지를 리스트로 받는다.

해설과 비교해 직접 채점
Python · 기본 · 창작 15미풀이

연산자 네 가지

출력을 쓰시오.

print(7 / 2, 7 // 2, 7 % 2, 2 ** 3)
정답과 풀이 확인

정답 3.5 3 1 8

/는 일반 나눗셈, //는 바닥 나눗셈, %는 나머지, **는 거듭제곱.

해설과 비교해 직접 채점
Python · 기본 · 창작 16미풀이

단락 평가의 반환값

출력을 쓰시오.

print(0 or 9, 3 and 4, not [])
정답과 풀이 확인

정답 9 4 True

0이 거짓이라 or는 9, 3이 참이라 and는 4, 빈 리스트가 거짓이라 not은 True.

해설과 비교해 직접 채점
Python · 응용 · 창작 17미풀이

append와 extend

출력을 쓰시오.

a=[1]
a.append([2,3])
a.extend([4,5])
print(a,a.pop())
정답과 풀이 확인

정답 [1, [2, 3], 4] 5

append는 리스트 한 개 추가, extend는 원소 각각 추가, pop은 마지막 5를 반환·삭제.

해설과 비교해 직접 채점
Python · 기본 · 창작 18미풀이

중첩 컴프리헨션 순서

출력을 쓰시오.

print([i*10+j for i in [1,2] for j in [3,4]])
정답과 풀이 확인

정답 [13, 14, 23, 24]

i=1일 때 j=3,4를 모두 처리한 뒤 i=2를 처리한다.

해설과 비교해 직접 채점
Python · 기본 · 창작 19미풀이

반복문 else

출력을 쓰시오.

for i in range(3):
    if i==1:
        continue
    print(i,end="")
else:
    print("E",end="")
정답과 풀이 확인

정답 02E

i=1은 continue, i=0,2는 출력. break 없이 종료하므로 E도 출력한다.

해설과 비교해 직접 채점
Python · 기본 · 창작 20미풀이

값과 객체

출력을 쓰시오.

a=[1,2]
b=a
c=a[:]
print(a==c,a is c,a is b)
정답과 풀이 확인

정답 True False True

c는 같은 값의 새 리스트, b는 a와 동일한 객체.

해설과 비교해 직접 채점
Python · 기본 · 창작 21미풀이

문자열 출력 경계

출력을 쓰시오.

print("A","B",sep=":",end="!")
print("C")
정답과 풀이 확인

정답 A:B!C

sep은 값 사이, end는 마지막에 붙는다. 첫 출력에 줄바꿈이 없어서 C가 바로 붙는다.

해설과 비교해 직접 채점
Python · 기본 · 창작 22미풀이

반환 없는 함수

출력을 쓰시오.

def f(x):
    print(x*2)
r=f(2)
print(r)
정답과 풀이 확인

정답 4
None

f는 4를 화면에 출력하지만 return이 없으므로 호출 결과는 None.

해설과 비교해 직접 채점
Python · 응용 · 창작 23미풀이

기본 인자 재사용

출력 결과를 쓰시오.

def f(a=[]):
    a.append(1)
    return len(a)
print(f(), f())
정답과 풀이 확인

정답 1 2

기본 리스트는 함수 정의 시 한 번 생성되어 두 호출에서 재사용된다.

해설과 비교해 직접 채점
Python · 응용 · 창작 24미풀이

반복한 행의 별칭

출력 결과를 쓰시오.

a = [[0]*2]*2
a[0][1] = 7
print(a)
정답과 풀이 확인

정답 [[0, 7], [0, 7]]

바깥 리스트의 두 칸은 같은 내부 리스트를 가리킨다.

해설과 비교해 직접 채점

기출과 연결하기

2024년 3회 · 문자열 비교·Python 슬라이싱·LRU·상속·C 연결 구조

2025년 2회 · 인덱스 접근·속성 용어·언어 실행 추적

2026년 2회 · 구조체·상속·딕셔너리·외부 조인·상관 서브쿼리·SRT·서브넷

문법 문서·출처·확인 범위 보기