좋아, 지금부터 이 5가지 트랩을 모두 실제 시험 문제 스타일로 내고,
한 줄씩 디버깅하듯 해설 + 실전 팁으로 완전히 해부해줄게!
del, pop(), remove() 차이 트랩lst = [1, 2, 3, 4]
del lst[1]
lst.remove(3)
x = lst.pop()
print(lst, x)
A. [1, 4], 4
B. [1], 4
C. [1, 3, 4], 4
D. [1, 2, 3], 4
lst = [1, 2, 3, 4]
del lst[1] # 1번 인덱스 삭제 → [1, 3, 4]
lst.remove(3) # 값 3을 삭제 → [1, 4]
x = lst.pop() # 마지막 요소 제거 & 반환 → x = 4, 남은 리스트: [1]
| 메서드 | 대상 | 반환값 | 사용 예 |
|---|---|---|---|
del lst[i] | 인덱스 | ❌ 없음 | del lst[0] |
pop(i) | 인덱스 | ✅ 삭제된 값 | x = lst.pop() |
remove(x) | 값 | ❌ 없음 | lst.remove(3) |
sorted() vs list.sort() 차이 트랩nums = [3, 1, 4]
sorted(nums)
nums.sort()
print(nums)
A. [1, 3, 4]
B. [3, 1, 4]
C. [4, 3, 1]
D. 에러 발생
sorted(nums) # 새 리스트 반환만 함 (반환값 무시됨) → 원본 영향 ❌
nums.sort() # 리스트 자체 정렬 → 원본 영향 O
sorted()는 원본을 건드리지 않고 새 정렬된 리스트 반환sort()는 리스트 객체 자체를 변경| 함수 | 원본 영향 | 반환값 |
|---|---|---|
sorted() | ❌ 없음 | 새 리스트 |
.sort() | ✅ 있음 | None 반환 |
copy() vs deepcopy() 비교 트랩import copy
a = [[1, 2], [3, 4]]
b = copy.copy(a)
b[0][0] = 99
print(a)
A. [[1, 2], [3, 4]]
B. [[99, 2], [3, 4]]
C. [[1, 2], [99, 4]]
D. [[99, 2], [99, 4]]
b = copy.copy(a) # 얕은 복사 → 1단계까지만 복사
b[0][0] = 99 # b[0]과 a[0]은 같은 리스트 → a[0][0]도 변경됨
📌 copy()는 리스트의 바깥 껍데기만 복사하고,
내부 요소는 여전히 원본과 공유됨.
| 함수 | 깊이 | 내부 요소 공유 여부 |
|---|---|---|
copy() | 얕은 복사 | ✅ 공유됨 |
deepcopy() | 깊은 복사 | ❌ 공유 안 됨 |
a = [1, 2]
b = [a, a]
a[0] = 99
print(b)
A. [[99, 2], [1, 2]]
B. [[99, 2], [99, 2]]
C. [[1, 2], [1, 2]]
D. 에러 발생
a = [1, 2]
b = [a, a] # b[0]과 b[1]이 **같은 a**를 참조
a[0] = 99 # 둘 다 같이 바뀜
b = [a, a]는 a를 두 번 참조하는 것이지, 복사한 게 아님a ───► [99, 2]
▲
│
└──── b[0], b[1] 모두 같은 리스트
리스트 안에 같은 리스트를 중복해서 넣을 때는copy.deepcopy() 또는 a.copy() 사용해야 함in 연산자의 진짜 동작 방식 (해시 기반)class Person:
def __init__(self, name):
self.name = name
p = Person("Alice")
d = {p: 1}
print(p in d)
print(Person("Alice") in d)
A. True, True
B. True, False
C. False, False
D. 에러 발생
Person("Alice") 두 객체가 다르므로 hash도 다르고 → in 결과는 Falsep in d # ✅ 같은 객체 → True
Person("Alice") in d # ❌ 다른 객체 → False
class Person:
def __init__(self, name):
self.name = name
def __eq__(self, other):
return self.name == other.name
def __hash__(self):
return hash(self.name)
이제는 Person("Alice") 객체끼리도 in dict에서 같게 인식됨.
| 키 비교 기준 | 설명 |
|---|---|
in dict | hash() → == 순서로 검사 |
| 사용자 정의 객체 | __eq__, __hash__ 없으면 서로 다른 객체로 판단 |
| 트랩 주제 | 실수 원인 | 정확한 동작 방식 |
|---|---|---|
del, pop(), remove() | 삭제 방식 혼동 | 인덱스 vs 값, 반환 여부 구분 |
sorted() vs sort() | 반환 vs 원본 변화 혼동 | sorted()는 새 리스트 |
copy() vs deepcopy() | 얕은 복사로 내부 공유 | deepcopy()로 안전 복사 |
| 리스트 내부 참조 | 같은 리스트 재사용 오해 | 참조는 한 번만 생성됨 |
in 연산자 (dict) | 객체 비교 시 False | hash와 == 둘 다 필요 |
좋아! 이번엔 요청한 5가지 주제를 하나씩 실전 코드 문제 + 보기 + 한 줄씩 쪼개서 완전 해부 + 핵심 요약으로 다뤄볼게.
정보처리기사 실기나 면접에서도 진짜 자주 나오는 트랩들이니 천천히 같이 파헤치자.
str() vs repr() 실전 트랩class Person:
def __str__(self):
return "str method"
def __repr__(self):
return "repr method"
p = Person()
print(str(p))
print(repr(p))
print(p)
print([p])
A.
str method
repr method
str method
repr method
B.
repr method
str method
repr method
str method
C.
str method
str method
str method
str method
D.
에러 발생
str(p) → __str__() 호출 → "str method"repr(p) → __repr__() 호출 → "repr method"print(p) → 내부적으로 str(p) 호출 → "str method"print([p]) → 리스트 출력 시 각 요소 repr() 호출 → "repr method"str()와 print()는 사람이 읽기 좋은 형태 출력 (즉, __str__)repr()와 컬렉션 출력은 개발자용 표현 (즉, __repr__)*args와 **kwargs 인자 전달 혼동 트랩def func(a, b=2, *args, **kwargs):
print(f"a={a}, b={b}, args={args}, kwargs={kwargs}")
func(1, 3, 4, 5, x=6, y=7)
A. a=1, b=3, args=(4, 5), kwargs={'x': 6, 'y': 7}
B. a=1, b=2, args=(3, 4, 5), kwargs={'x': 6, 'y': 7}
C. a=1, b=3, args=(), kwargs={'x': 6, 'y': 7}
D. 에러 발생
a=1 → 첫 번째 위치 인자b=3 → 두 번째 위치 인자 (기본값 대신 전달됨)args=(4,5) → 위치 인자 초과분 (4,5)kwargs={'x':6, 'y':7} → 키워드 인자 모두 수집*args는 위치 인자 추가 수집**kwargs는 키워드 인자 추가 수집__init__에서 기본값 변경 문제 (가변 객체 주의)class Test:
def __init__(self, data=[]):
self.data = data
t1 = Test()
t1.data.append(1)
t2 = Test()
print(t2.data)
A. []
B. [1]
C. None
D. 에러 발생
data=[]는 함수 정의 시 한 번만 생성됨t1.data와 t2.data가 같은 리스트 공유됨 → [1] 포함된 상태print(t2.data) 출력 시 [1]class Test:
def __init__(self, data=None):
if data is None:
data = []
self.data = data
None으로 초기화하고 함수 내에서 새 객체 생성해야 함int, str) 참조 최적화 트랩a = 1000
b = 1000
print(a is b)
x = 10
y = 10
print(x is y)
A. True, True
B. False, False
C. False, True
D. True, False
a is b는 Falsex is y는 Trueis는 객체 동일성 비교이며, ==와 혼동하지 말 것a = [1, 2, 3]
b = (1, 2, 3)
print(type(a), type(b))
a[0] = 99
b[0] = 99
A. <class 'list'> <class 'tuple'>
에러 발생
B. <class 'list'> <class 'tuple'>
[99, 2, 3] 출력
C. <class 'list'> <class 'tuple'>
[1, 2, 3] 출력
D. 에러 발생
b[0] = 99에서 TypeError 발생| 주제 | 핵심 트랩 요약 |
|---|---|
str() vs repr() | 출력 상황에 따라 호출 메서드 다름 |
*args, **kwargs | 위치, 키워드 인자 혼동 주의 |
__init__ 기본값 변경 | 가변 객체 기본값 공유 주의 |
| 불변 객체 최적화 | 작은 숫자/문자열 객체 재사용 |
| 리스트 vs 튜플 | 튜플은 불변이라 수정 시 에러 발생 |