요소가 문자열인 목록(배열)에서 새 목록을 생성하려면 특정 조건을 만족하는 문자열의 요소만 추출하거나 대체, 변환 등을 수행하여 목록 이해를 사용합니다.
리스트 컴프리헨션에 대한 간략한 설명 후, 샘플 코드와 함께 다음 내용을 설명합니다.
- 특정 문자열의 포함 여부에 따른 추출(부분일치)
- 특정 문자열 바꾸기
- 특정 문자열로 시작하거나 시작하지 않고 추출
- 특정 문자열로 끝나거나 끝나지 않고 추출
- 사례별로 판단 및 추출
- 대문자와 소문자 변환
- 영문자 또는 숫자의 사용 여부를 판별하여 추출합니다.
- 여러 조건
- (컴퓨터) 정규식
목록은 다양한 유형의 데이터를 저장할 수 있으며 배열과 완전히 다릅니다. 메모리 크기와 메모리 주소가 필요한 프로세스에서 배열을 처리하거나 대용량 데이터의 수치 처리를 수행하려면 배열(표준 라이브러리) 또는 NumPy를 사용하십시오.
목록 포함 표기법
목록에서 새 목록을 생성할 때 목록 이해는 for 루프보다 작성하기가 더 간단합니다.
[expression for any variable name in iterable object if conditional expression]
요소가 조건식으로만 선택되어야 하는 경우에는 표현식으로 처리하지 않으므로 다음과 같은 형식을 취합니다.
[variable name for variable name in original list if conditional expression]
if 조건식을 if not 조건식으로 만들면 부정이 되어 조건식을 만족하지 않는 요소를 추출할 수 있다.
특정 문자열을 포함합니다(부분 일치) \ 포함하지 않음:in
“원래 문자열의 특정 문자열”에서 원본 문자열에 특정 문자열이 포함되어 있으면 True를 반환합니다. 이것은 조건식입니다.
in의 부정은 not in으로 수행됩니다.
l = ['oneXXXaaa', 'twoXXXbbb', 'three999aaa', '000111222']
l_in = [s for s in l if 'XXX' in s]
print(l_in)
# ['oneXXXaaa', 'twoXXXbbb']
l_in_not = [s for s in l if 'XXX' not in s]
print(l_in_not)
# ['three999aaa', '000111222']
특정 문자열 바꾸기
목록 요소의 문자열을 바꾸려면 목록 이해 표기법의 각 요소에 대해 문자열 메서드 replace()를 사용하십시오.
교체할 문자열이 없으면 replace()를 적용해도 변경되지 않으므로 if 조건식에서 요소를 선택할 필요가 없습니다.
l_replace = [s.replace('XXX', 'ZZZ') for s in l]
print(l_replace)
# ['oneZZZaaa', 'twoZZZbbb', 'three999aaa', '000111222']
특정 문자열을 포함하는 전체 요소를 교체하려면 in으로 추출하고 삼항 연산자로 처리하십시오. 삼항 연산자는 다음 형식으로 작성됩니다.True Value if Conditional Expression else False Value
목록 이해 표기법의 표현 부분이 삼항 연산자이면 OK입니다.
l_replace_all = ['ZZZ' if 'XXX' in s else s for s in l]
print(l_replace_all)
# ['ZZZ', 'ZZZ', 'three999aaa', '000111222']
다음은 괄호로 묶인 결과를 요약한 것입니다. 괄호 사용에 익숙하지 않다면 이해하기 쉬우며 실수를 피할 수 있습니다. 문법적으로는 괄호를 써도 문제 없습니다.
[('ZZZ' if ('XXX' in s) else s) for s in l]
in을 조건으로 사용하는 것은 in의 목록 이해 표기법과 혼동되지만 목록 이해 표기법과 삼항 연산자의 구문 형식을 알고 있으면 어렵지 않습니다.
특정 문자열로 시작 \ 시작하지 않음:startswith()
문자열 메서드 startswith()는 문자열이 인수에 지정된 문자열로 시작하는 경우 true를 반환합니다.
l_start = [s for s in l if s.startswith('t')]
print(l_start)
# ['twoXXXbbb', 'three999aaa']
l_start_not = [s for s in l if not s.startswith('t')]
print(l_start_not)
# ['oneXXXaaa', '000111222']
특정 문자열로 끝납니다. \ not end:endswith()
문자열 메서드 endwith()는 문자열이 인수에 지정된 문자열로 끝나는 경우 true를 반환합니다.
l_end = [s for s in l if s.endswith('aaa')]
print(l_end)
# ['oneXXXaaa', 'three999aaa']
l_end_not = [s for s in l if not s.endswith('aaa')]
print(l_end_not)
# ['twoXXXbbb', '000111222']
사례별로 판단 및 추출
문자열 메서드 isupper(),islower()를 사용하여 문자열이 모두 대문자인지 아니면 모두 소문자인지 확인할 수 있습니다.
l_lower = [s for s in l if s.islower()]
print(l_lower)
# ['three999aaa']
대문자와 소문자 변환
모든 문자를 대문자 또는 소문자로 변환하려면 문자열 메서드 upper() 및 lower()를 사용하십시오. 다른 메서드에는 첫 글자만 대문자로 표시하는 Capitalize()와 대문자와 소문자를 바꾸는 swapcase()가 있습니다.
위의 치환 예와 같이 조건을 만족하는 요소만 처리하고 싶다면 삼항 연산자를 사용한다.
l_upper_all = [s.upper() for s in l]
print(l_upper_all)
# ['ONEXXXAAA', 'TWOXXXBBB', 'THREE999AAA', '000111222']
l_lower_to_upper = [s.upper() if s.islower() else s for s in l]
print(l_lower_to_upper)
# ['oneXXXaaa', 'twoXXXbbb', 'THREE999AAA', '000111222']
영문자 또는 숫자의 사용 여부를 판별하여 추출합니다.
문자열 메서드 isalpha() 및 isnumeric()을 사용하여 문자열이 모두 알파벳, 숫자 등인지 여부를 확인할 수 있습니다.
l_isalpha = [s for s in l if s.isalpha()]
print(l_isalpha)
# ['oneXXXaaa', 'twoXXXbbb']
l_isnumeric = [s for s in l if s.isnumeric()]
print(l_isnumeric)
# ['000111222']
여러 조건
목록 내포의 조건식 부분은 여러 조건이 될 수 있습니다. 부정 “not” 조건도 사용할 수 있습니다.
3개 이상의 조건식을 사용할 경우 순서에 따라 결과가 달라지므로 각 그룹을 괄호()로 묶는 것이 더 안전하다.
l_multi = [s for s in l if s.isalpha() and not s.startswith('t')]
print(l_multi)
# ['oneXXXaaa']
l_multi_or = [s for s in l if (s.isalpha() and not s.startswith('t')) or ('bbb' in s)]
print(l_multi_or)
# ['oneXXXaaa', 'twoXXXbbb']
(컴퓨터) 정규식
정규식은 매우 유연한 처리를 허용합니다.
re.match()가 일치할 때 반환하는 일치 개체는 조건식으로 평가할 때 항상 참으로 결정됩니다. 일치하지 않으면 조건식에서 false인 None을 반환합니다. 따라서 정규식과 일치하는 요소만 추출하려면 이전과 같이 목록 이해식의 조건식 부분에 re.match()를 적용하면 됩니다.
import re
l = ['oneXXXaaa', 'twoXXXbbb', 'three999aaa', '000111222']
l_re_match = [s for s in l if re.match('.*XXX.*', s)]
print(l_re_match)
# ['oneXXXaaa', 'twoXXXbbb']
정규식의 일치하는 부분을 대체하는 re.sub()도 유용합니다. 일치하는 요소만 추출하고 바꾸려면 “if conditional expression”을 추가하면 됩니다.
l_re_sub_all = [re.sub('(.*)XXX(.*)', r'\2---\1', s) for s in l]
print(l_re_sub_all)
# ['aaa---one', 'bbb---two', 'three999aaa', '000111222']
l_re_sub = [re.sub('(.*)XXX(.*)', r'\2---\1', s) for s in l if re.match('.*XXX.*', s)]
print(l_re_sub)
# ['aaa---one', 'bbb---two']