함수·리스트·복사와 작은 검사
인자와 반환값, 0부터 시작하는 인덱스, 원본과 복사를 구분합니다.
같은 문제를 여러 입력으로 확인하려면 계산을 함수로 묶어야 합니다. 이 본문의 목표는 입력을 함수에 전달하고 결과를 받는 과정, 그리고 원본 리스트를 바꿨는지 확인하는 방법을 익히는 것입니다. 변수·반복을 복습한 뒤 진행하세요.
개념과 약속
함수는 def 이름(인자):로 정의합니다. 인자는 함수에 건네는 입력이고 return은 호출한 곳에 결과를 돌려줍니다. print로 화면에 보여 주는 일과 반환하는 일은 다릅니다. 리스트는 순서가 있는 값의 모음입니다. [4, 1, 3]의 길이는 len(values)로 얻고, 첫 원소는 values[0]입니다. 마지막 인덱스는 길이에서 1을 뺀 값입니다.
copy = values는 복사하지 않고 같은 리스트를 가리킵니다. 새 리스트가 필요하면 list(values) 또는 슬라이스 values[:]를 사용합니다. 이것은 중첩 리스트 내부까지 새로 만드는 깊은 복사가 아닙니다. assert 조건은 조건이 거짓이면 검사 실패를 알립니다. 학습 중 오류 탐지에 쓰며 외부 입력 검증은 뒤에서 ValueError처럼 명시적으로 처리합니다.
뒤의 코드에서 [value * 2 for value in values]처럼 반복 결과를 한 식으로 모으는 리스트 컴프리헨션을 만납니다. 이 식은 아래 함수의 반복과 같은 새 목록을 만듭니다. 끝에 if 조건을 붙이면 조건이 참인 원소만 포함합니다. a, b = b, a 같은 묶음 대입은 오른쪽을 기존 값으로 먼저 계산한 뒤 함께 대입해 두 값을 안전하게 바꿉니다.
자료구조·알고리즘 · 상태와 관계
같은 이름값과 실제 복사
values와 alias는 하나의 리스트를 가리키지만 copy는 새 리스트입니다.
화살표는 변수 이름이 가리키는 객체입니다. 강조한 새 리스트를 바꾸어도 위 리스트의 숫자 원소는 바뀌지 않습니다. 중첩 객체의 깊은 복사를 뜻하지는 않습니다.
손으로 상태 추적하기
| 시점 | values | doubled | 설명 |
|---|---|---|---|
| 호출 전 | [4, 1, 3] | 없음 | 원본을 전달한다 |
| 반복 첫 단계 | [4, 1, 3] | [8] | 새 목록에 넣는다 |
| 반환 후 | [4, 1, 3] | [8, 2, 6] | 원본과 결과가 다르다 |
| 빈 입력 | [] | [] | 반복 0회도 반환한다 |
직접 실행하기
아래 코드는 이 본문만으로 실행할 수 있습니다. lesson.py로 저장하고 첫 장에서 확인한 Python 명령으로 실행하세요.
def double_all(values):
result = []
for value in values:
result.append(value * 2)
return result
values = [4, 1, 3]
doubled = double_all(values)
print(values)
print(doubled)
assert doubled == [8, 2, 6]
assert values == [4, 1, 3]
assert double_all([]) == []
print("검사 통과")실행 결과:
[4, 1, 3]
[8, 2, 6]
검사 통과왜 맞고 언제 끝나는가
처리한 앞부분의 원소마다 두 배의 값 하나를 새 목록에 넣습니다. 끝나면 결과의 길이와 입력의 길이가 같고 대응하는 원소가 모두 두 배입니다. 빈 리스트에서는 for가 실행되지 않아 빈 결과를 반환합니다. 유한한 리스트 길이만큼만 반복하므로 종료합니다.
비용과 적용 범위
입력이 n개이면 n번 곱셈하고 결과 n개를 저장합니다. 시간과 추가 공간 모두 O(n)입니다. 복사해서 원본을 보존하는 선택에도 비용이 있음을 기억하세요.
스스로 풀어 보기
- 반환 결과의 첫 원소를 99로 바꾸면 원본 첫 원소도 바뀔까요?
- 함수의
return result를print(result)로 바꾸면doubled는 무엇이 될까요?
힌트
- 함수가 새 리스트를 만들었는지 살핍니다.
- 명시적인 반환이 없는 함수는
None을 반환합니다.
해설
- 바뀌지 않습니다. 숫자 리스트의 새 결과를 만들었기 때문입니다.
- 목록은 출력되지만 호출의 반환값은
None입니다. 화면 출력만 보고 함수 결과가 맞다고 판단하면 이 차이를 놓칩니다.
흔한 오해
모든 assert가 통과했다고 모든 입력에서 맞는 것은 아닙니다. 일반 입력뿐 아니라 빈 입력·중복값·경계값을 고르고 왜 그 경우가 필요한지 설명해야 합니다.
복습과 다음 연결
다음 절의 문제와 입출력에서는 함수가 지켜야 하는 약속을 먼저 적습니다. 리스트에 대한 공식 문법은 Python 자료구조에 있습니다.