본문으로 건너뛰기

리스트를 제자리에서 바꾸기

파이썬 목차리스트와 튜플레슨 25 / 59

목차

리스트 메서드 append()·extend()·remove()와 자리 번호 대입은 새 리스트를 만들지 않고 그 리스트를 제자리에서 바꿉니다. 세 메서드는 리스트를 바꿀 뿐 새 값을 돌려주지 않습니다.

문자열 메서드는 원래 문자열을 두고 새 문자열을 만들었습니다(s = s.upper()). 세 메서드는 거꾸로 같은 리스트를 바꿉니다. 둘을 섞어 생각하면 바뀐 리스트를 그대로라고 여기거나, 결과에 이름을 다시 붙이다 리스트를 잃습니다.

7단계 중 1단계. 리스트 하나를 메서드와 대입으로 바꾸는 코드입니다.

1리스트 하나가 제자리에서 바뀐다

그림의 코드입니다.

orders = ['커피']
orders.extend(['라테', '녹차'])
orders.remove('커피')
orders[0] = '쿠키'
print(orders)
실행 결과
['쿠키', '녹차']

2번 줄 extend()는 받은 리스트에서 값을 하나씩 꺼내 끝에 더합니다. 3번 줄 remove()는 처음 찾은 '커피' 하나를 지우고, 뒤 칸들이 한 칸씩 앞으로 옵니다. 4번 줄은 0번 칸을 '쿠키'로 바꿉니다. 문자열은 한 칸에 대입할 수 없었지만 리스트는 됩니다. 네 줄 내내 이름 orders는 처음 리스트 ①에 붙어 있고, 그 리스트의 칸이 늘고 빠지고 바뀌었습니다. 그림에서도 orders의 화살표는 한 번도 움직이지 않습니다(규칙 3).

2돌려주는 값은 None

코드하는 일돌려주는 값
orders.append('쿠키')끝에 값 하나를 더한다None
orders.extend(['라테', '녹차'])받은 것에서 값을 하나씩 꺼내 끝에 더한다None
orders.remove('커피')처음 찾은 '커피' 하나를 지운다None
orders[0] = '쿠키'0번 칸을 '쿠키'로 바꾼다없음(대입문)

None은 '돌려줄 값이 없다'는 뜻의 값입니다. 세 메서드는 리스트를 바꾸는 일을 하고 None을 돌려줍니다. 그래서 문자열 메서드처럼 결과에 이름을 다시 붙이지 않고, orders.append('쿠키')처럼 한 줄로 씁니다. 이 밖에 insert(자리 번호, 값)은 그 자리에 값을 끼우고, pop()은 끝 칸을 빼서 그 값을 돌려줍니다.

append()와 extend()에 같은 리스트를 넘기면 무엇이 찍힐까요?

a = [1]
b = [1]
a.append([2, 3])
b.extend([2, 3])
print(a)
print(b)
실행 결과 보기
실행 결과
[1, [2, 3]]
[1, 2, 3]

예상과 다르면 그곳이 배울 곳입니다. append()는 받은 값 하나를 통째로 한 칸에 더합니다. 리스트를 넘기면 그 리스트가 한 칸에 들어가 a는 칸이 둘입니다. extend()는 받은 리스트에서 값을 하나씩 꺼내 더해 b는 칸이 셋입니다.

예제

없는 값 지우기

주문에 없는 '커피'를 지우려 했습니다.

orders = ['라테', '녹차']
item = '커피'
orders.remove(item)
실행 결과
Traceback (most recent call last):  File "main.py", line 3, in <module>    orders.remove(item)    ~~~~~~~~~~~~~^^^^^^ValueError: list.remove(x): x not in list

맨 아래 줄은 'list.remove(x)에서 x가 리스트에 없다'는 뜻입니다. remove()는 지울 값을 찾지 못하면 그 줄에서 멈춥니다.

자주 틀리는 곳

틀린 생각: append()에 리스트를 넘기면 그 값들이 하나씩 더해진다.

extend()와 이름만 다른 것 같지만, append()는 받은 것을 통째로 한 칸에 더합니다.

a = [1]
a.append([2, 3])
print(len(a))
실행 결과
2

칸은 1과 [2, 3] 둘입니다.

맞는 규칙: append()는 받은 값 하나를 한 칸에 더하고, extend()는 받은 것에서 값을 하나씩 꺼내 더합니다. 값 여럿을 이어 더하려면 extend()를 씁니다.

틀린 생각: append()도 s = s.upper()처럼 결과에 이름을 다시 붙여야 한다.

문자열 메서드는 그렇게 썼지만, append()·extend()·remove()는 리스트를 바꾸고 None을 돌려줍니다.

x = [1]
x = x.append(2)
print(x)
실행 결과
None

2번 줄은 리스트에 2를 더한 뒤, 돌려받은 None에 x를 다시 붙입니다. 2를 더한 리스트는 가리키는 이름이 없어져 다시 꺼낼 수 없습니다.

맞는 규칙: append()·extend()·remove()는 그 리스트를 제자리에서 바꾸고 None을 돌려줍니다. 그래서 x.append(2)처럼 이름을 다시 붙이지 않고 씁니다(규칙 3).

확인 문제

1. 1절 코드의 2번 줄을 orders.extend(['라테', '커피'])⁠로 바꿨습니다. 무엇이 찍힐까요?

orders = ['커피']
orders.extend(['라테', '커피'])
orders.remove('커피')
orders[0] = '쿠키'
print(orders)
힌트

줄마다 리스트의 칸을 적어 봅니다. 3번 줄의 remove()가 하는 일은 2절 표에 있습니다.

정답
실행 결과
['쿠키', '커피']

2번 줄 뒤 ['커피', '라테', '커피'], 3번 줄이 처음 찾은 '커피' 하나만 지워 ['라테', '커피'], 4번 줄이 0번 칸을 바꿔 ['쿠키', '커피']입니다.

흔한 오답은 ['쿠키']입니다. remove()가 '커피'를 모두 지운다고 본 것입니다. remove()는 처음 찾은 하나만 지웁니다.

2. 실행 결과가 아래 한 줄이 되도록 빈칸을 채우세요. 3번 줄 하나로 두 값을 더합니다.

['라테', '쿠키', '녹차']
orders = ['커피', '라테']
orders.remove('커피')
orders.________
print(orders)
힌트

2절 표의 메서드를 하나씩 넣어 보며, 찍히는 리스트가 칸 셋인지 봅니다.

정답

extend(['쿠키', '녹차'])입니다.

orders = ['커피', '라테']
orders.remove('커피')
orders.extend(['쿠키', '녹차'])
print(orders)
실행 결과
['라테', '쿠키', '녹차']

흔한 오답은 append(['쿠키', '녹차'])입니다. 그러면 리스트가 통째로 한 칸에 들어가 ['라테', ['쿠키', '녹차']]가 찍힙니다. append()도 값을 하나씩 더한다고 본 것입니다.

3. 장보기 목록에 빵을 더한 뒤 개수를 찍으려 했는데 오류가 났습니다. 몇 번 줄을 어떻게 고쳐야 할까요?

cart = ['우유']
cart = cart.append('빵')
print(len(cart))
실행 결과
Traceback (most recent call last):  File "main.py", line 3, in <module>    print(len(cart))          ~~~^^^^^^TypeError: object of type 'NoneType' has no len()
힌트

3번 줄에서 cart가 무엇을 가리키는지, 그 값에 이름을 붙인 줄로 거슬러 올라가 봅니다.

정답

2번 줄을 cart.append('빵')으로 고칩니다.

cart = ['우유']
cart.append('빵')
print(len(cart))
실행 결과
2

NoneType은 None의 종류 이름입니다. 고치기 전 2번 줄은 리스트에 빵을 더한 뒤, append()가 돌려준 None에 cart를 다시 붙였습니다. 오류는 3번 줄에서 났지만 고칠 곳은 그 값에 cart를 붙인 2번 줄입니다.

다르게 고쳐도 되는 곳: 2번 줄을 cart = cart + ['빵']으로 써도 2가 찍힙니다. +는 빵까지 담은 새 리스트를 만들고, cart를 그 리스트에 다시 붙입니다. cart.extend(['빵']) · cart.insert(1, '빵')도 2가 찍힙니다.

흔한 오답은 3번 줄만 print(cart)로 고치는 것입니다. 오류가 난 줄이 곧 고칠 줄이라고 본 것입니다. 오류는 사라지지만 None이 찍히고, 빵을 더한 리스트는 이미 잃었습니다.

아래 코드 2번 줄의 리스트 ['라테', '녹차']를 문자열 '라테'로 바꾸면 무엇이 찍히는지 봅니다.

처음 펼 때 약 6MB를 받습니다.컴퓨터에서 해 보기

끝까지 내려오면 저절로 표시됩니다. 이 기기에만 저장합니다.

파이썬 목차로