파이썬에서 문자열 목록(배열)의 조건을 만족하는 요소 추출 및 바꾸기

사업

요소가 문자열인 목록(배열)에서 새 목록을 생성하려면 특정 조건을 만족하는 문자열의 요소만 추출하거나 대체, 변환 등을 수행하여 목록 이해를 사용합니다.

리스트 컴프리헨션에 대한 간략한 설명 후, 샘플 코드와 함께 다음 내용을 설명합니다.

  • 특정 문자열의 포함 여부에 따른 추출(부분일치)
  • 특정 문자열 바꾸기
  • 특정 문자열로 시작하거나 시작하지 않고 추출
  • 특정 문자열로 끝나거나 끝나지 않고 추출
  • 사례별로 판단 및 추출
  • 대문자와 소문자 변환
  • 영문자 또는 숫자의 사용 여부를 판별하여 추출합니다.
  • 여러 조건
  • (컴퓨터) 정규식

목록은 다양한 유형의 데이터를 저장할 수 있으며 배열과 완전히 다릅니다. 메모리 크기와 메모리 주소가 필요한 프로세스에서 배열을 처리하거나 대용량 데이터의 수치 처리를 수행하려면 배열(표준 라이브러리) 또는 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']