32.4 연습문제
, 조 성운님이 작성먼저, 좋은 자료 덕북에 재미있게 python을 공부하고 있습니다.
32.4의 연습문제 정답 수정이 필요해 보입니다.
주어진 files 리스트에 '4.pngaaa'를 추가한 후에 현재 정답으로 나온 코드를 실행하면 '4.pngaaa'도 결과에 출력됩니다.
files = ['font', '1.png', '10.jpg', '11.gif', '2.jpg', '3.png', 'table.xslx', 'spec.docx', '4.pngaaa']
>>> list(filter(lambda x: x.find('.jpg') != -1 or x.find('.png') != -1, files))
['1.png', '10.jpg', '2.jpg', '3.png', '4.pngaaa']
저는 아래처럼 작성을 했습니다.
>>> list(filter(lambda x: x[len(x) - len('.png'):] == '.png' or x[len(x) - len('.jpg'):] == '.jpg', files))
Re: 32.4 연습문제
, 도장_ 관리자님이 작성작가님에게 문의를 하고 답변을 받았습니다.
-----
32.4 연습문제는 람다 표현식과 filter 사용 방법을 설명하는 것이 목적이라 확장자 검사 부분은 의도된 것입니다.
먼저 연습 문제의 코드에서는
files = ['font', '1.png', '10.jpg', '11.gif', '2.jpg', '3.png', 'table.xslx', 'spec.docx']
와 같이 .png, .jpg, .gif, .xslx, .docx만 제시하고 있으므로 문자열의 find 메서드로도 실행 결과를 만족할 수 있습니다.
.pngaaa와 같은 케이스도 정확하게 처리하기 위한 방법은 연습 문제에서 설명하고자 한 부분이 아니라서 생략하였습니다. 이점 양해부탁드립니다.
참고로 .pngaaa와 같은 케이스를 처리할 때는 보통 정규표현식을 사용하게 됩니다(정규표현식은 책 후반부에 나옵니다. 아직 배우지 않은 부분은 활용할 수 없으므로 연습 문제에서는 find로 대신하였습니다).
import re
files = ['1.pngaaa', '2.png', '3.jpgaaa', '4.jpg']
print(list(filter(lambda x: re.search('.jpg$', x) or re.search('.png$', x), files)))
files = ['1.pngaaa', '2.png', '3.jpgaaa', '4.jpg']
print(list(filter(lambda x: re.search('.jpg$', x) or re.search('.png$', x), files)))
# 출력결과: ['2.png', '4.jpg']
이렇게
re.search('.png$', x)와 같이 정규표현식 '.png$'를 작성해서 .png로 끝나는 문자열만 검사할 수 있습니다. 이렇게 하면 .pngaaa는 걸러낼 수 있습니다.
또한, 책에서는 분량 문제로 설명하지는 않았지만 os.path.splitext 함수나 문자열의 endswith 메서드를 활용해도 상관없습니다.
os.path.splitext 함수는 경로에서 파일명과 확장자를 분리하는 함수이고, endswith 메서드는 문자열이 특정 문자열로 끝나는지 검사하는 함수입니다. 따라서 .pngaaa를 걸러낼 수 있습니다.
import os
files = ['1.pngaaa', '2.png', '3.jpgaaa', '4.jpg']
print(list(filter(lambda x: os.path.splitext(x)[1] == '.jpg' or os.path.splitext(x)[1] == '.png', files)))
files = ['1.pngaaa', '2.png', '3.jpgaaa', '4.jpg']
print(list(filter(lambda x: os.path.splitext(x)[1] == '.jpg' or os.path.splitext(x)[1] == '.png', files)))
# 출력결과: ['2.png', '4.jpg']
files = ['1.pngaaa', '2.png', '3.jpgaaa', '4.jpg']
print(list(filter(lambda x: x.endswith('.jpg') or x.endswith('.png'), files)))
print(list(filter(lambda x: x.endswith('.jpg') or x.endswith('.png'), files)))
# 출력결과: ['2.png', '4.jpg']