람다식에 split을 두 번 넣어서 에러가 발생하는 게 아니라 아마도 문법이 잘못되었을 겁니다. 람다식이 아니어도 에러가 발생했을 겁니다.
UNIT 32.1.3의 예제 코드를 보면
list(map(plus_ten, [1, 2, 3]))
이라는 예제가 있습니다.
심사문제의 요구사항은 리스트로 출력하세요 이니 list를 씁니다.
map으로 데이터에 함수를 적용합니다.
심사문제 32.5로 바꿔보면
예시로 보여주는 파일명을 files로 넣어봅시다.
files = ['1.jpg', '10.png', '11.png', '2.jpg', '3.png']
제시 코드에서는
files = input().split()
인데, 그 결과는 파일명으로 된 리스트겠지요.
print(____________________) 안에 코드를 채워야 합니다.
UNIT 32.1.3의 예제는 인터랙티브 모드에서 실행했으니 결과가 나오지만, 심사에서는 파일 모드로 실행하니 print()로 출력하는 것입니다.
print( list(map(plus_ten, [1, 2, 3])) )
이런 구조이지요.
[1, 2, 3]은 files라는 파일명 리스트로 바꾸면 됩니다.
print( list(map(plus_ten, files)) )
plus_ten은 함수였죠. 이름을 바꿀까요.
name_files라고 바꾸죠.
print( list(map(name_files, files)) )
이제 name_files 함수를 작성해서 문제가 요구하는 결과가 나오게 해봅니다.
그 이후에 name_files를 람다식으로 바꾸면 됩니다.
람다식이 익숙하지 않을 때는
1. 먼저 동작하는 함수를 만들어본다
2. 동작하는 함수를 람다식으로 변환한다
라는 절차를 거치는 게 좋습니다.
UNIT 32.1.3을 보면 list(map(plus_ten, ...))에서 람다식으로 바꾼 후에는
list(map(lambda x: ...))로 되었습니다.
UNIT 32.5의 심사문제에서 print 안에 넣어야 하는 코드도
list(map(lambda x: ...))겠죠?
동일한 코드 구조입니다.
리스트에 있는 파일명을 받아서 한 번에 변환하는 게 어렵다면 문제를 더 작은 문제로 분해하면 됩니다. UNIT 1 기억하시죠? 문제 해결을 위한 과학적 사고, 즉 컴퓨팅 사고력은 큰 문제를 작은 문제로 분해하는 것에서 시작합니다.
1.jpg를 001.jpg로 바꾸는 것부터 작성해봅니다. 먼저 다음과 같은 코드부터 테스트해보죠. 이건 문의에 적은 코드를 재활용한 겁니다.
>>> x = '1.jpg'
>>> x
'1.jpg'
>>> x.split('.')[0]
'1'
>>> print('{0}'.format( x.split('.')[0] ))
1
>>>
문의한 코드나 여기서 실습한 코드나 파일명 1.jpg에서 1만 출력됩니다. 001로 출력하는 것에는 실패하고 있습니다.
001.jpg로 출력하기 위해서는 포맷을 테스트해야 합니다.
>>> '{0}.{1}'.format('1', 'jpg')
'1.jpg'
기본 형식은 테스트했습니다.
이제 앞에 00만 붙이게, 3자리로 출력하게 하면 됩니다.
>>> '{0:03d}.{1}'.format('1', 'jpg')
Traceback (most recent call last):
File "<pyshell#15>", line 1, in <module>
'{0:03d}.{1}'.format('1', 'jpg')
ValueError: Unknown format code 'd' for object of type 'str'
>>> '{0:03d}.{1}'.format(1, 'jpg')
'001.jpg'
>>>
첫 번째 시도에서 'd'는 문자열에 쓸 수 없다고 나옵니다. 파일명 앞은 숫자로 처리하라는 것을 알 수 있습니다.
여기까지 테스트했으면, 이제 리스트에 있는 문자열 '1.jpg'를 나누었을 때 1은 숫자로 바꾸고, jpg는 문자열 그대로 쓰면 된다는 것을 알았습니다.
심사문제 해설을 보시면
문자열 포매팅을 '{0:03d}.{1}'와 같이 만들어줍니다. 먼저 {0:03d}는 파일 이름 부분이며 숫자 1은 001, 99는 099, 100은 100처럼 숫자 3개로 만들고 앞에 0이 들어갑니다. 그리고 {1}은 확장자 부분이며 문자열이 그대로 들어갑니다.
서식도 알려드리고 있습니다. 숫자라는 것도 알려주고, 확장자는 문자열이라는 것도 알려줍니다.
이제 '{0:03d}.{1}'에 format 메서드를 사용해서 내용을 채웁니다. 먼저 문자열은 split('.')처럼 '.'을 기준으로 분리해서 파일 이름과 확장자로 나눕니다. 그리고 lambda에서 매개변수로 x를 지정했다면 int(x.split('.')[0])과 같이 파일 이름 부분을 얻습니다. 즉, 1.png는 split('.')으로 분리했을 때 리스트 ['1', 'png']가 나오는데 첫 번째 요소를 사용해야 하므로 [0]입니다. 그리고 {0:03d}에는 숫자가 들어가야 하므로 int를 사용해서 정수로 변환해줍니다.
split으로 분리하면 리스트가 나오고, 앞에는 숫자가 필요하니 int를 사용해서 정수로 변환하라는 힌트도 제공합니다.
전체적으로 다시 한 번 정리합시다.
1. 먼저 동작하는 함수를 작성한다.
2. 동작하는 함수를 람다식으로 변환한다.
함수를 작성할 때
1. 문제가 크다면 더 작은 문제로 나눈다.
2. 더 작은 문제를 해결하는 코드를 작성한다.
3. 작은 문제를 해결한 코드를 모아 큰 문제를 해결하는 코드로 완성한다.
같은 절차를 거치면 됩니다.
UNIT 32.1.3의 예제를 벗어나지 않습니다. split은 UNIT 7부터 사용하기 시작해서 <파이썬 코딩 도장> 전체에서 약 150회 반복됩니다.
format는 UNIT 24.2에서 설명하고 전체에서 약 130회 반복됩니다.
전혀 모르겠다면 IDLE에서 코드를 이것저것 테스트해봅니다.
UNIT 31, 32를 다시 학습합니다. split과 format을 알아야 하면 UNIT 7, 24를 학습합니다.
심사문제의 해설을 자세히 읽어봅니다.
그래도 안 될 때는 넘어가세요. 책을 1회 공부하고, 2회 공부할 때 자연히 이해되고 해결됩니다.
코딩도장의 심사문제는 이해도를 묻는 것이 목적입니다. 누구나 반복하고, 학습하면 이해할 수 있는 것이 목표이고, 설령 심사문제를 풀지 못해도 해설에서 거의 정답 수준으로 힌트를 제공하고 있습니다.
또한, 앞에 나온 예제나 연습문제 수준을 넘어가지 않게 했습니다.
람다식 자체가 익숙한 것이 아니기 때문에 처음에 어려움을 겪습니다. 처음부터 람다식을 작성하지 말고 함수부터 작성해서 테스트해보세요.
람다식은 사용빈도가 높은 편이라서 확실하게 이해하는 게 좋습니다. 익숙해질 때까지는 함수부터 작성하세요. 자전거의 보조 바퀴라고 생각해도 될 것 같습니다.
같이 공부하는 친구들과도 논의해보세요. "나중을 기약하며" 포스트잇을 붙여두는 것도 좋습니다.
홧팅!