08장 파이썬 강좌 – 정규표현식

정규표현식(Regular Expressions)은 문자열 내에서 특정한 패턴을 찾거나 대체하는 데 사용되는 매우 강력한 도구입니다. 그는 많은 프로그래밍 언어에서 지원되며, 특히 텍스트 처리를 자주 필요로 하는 작업에서 필수적인 기술입니다.

이 강좌에서는 파이썬의 내장 모듈인 re 모듈을 사용하여 정규표현식을 다루는 방법을 배울 것입니다. 이 모듈은 문자열 검색 및 변경, 패턴 매칭과 같은 정규표현식의 거의 모든 기능을 제공합니다.

정규표현식 기본 개념

정규표현식은 특정 패턴을 사용하여 문자열을 검색하는 방법의 일종입니다. 대부분의 텍스트 편집기에서 지원하며, 프로그래밍 언어에서도 널리 사용됩니다. 정규표현식은 일종의 미니언어로 간주될 수 있으며, 문자열을 처리하고 분석하는 데 있어 매우 유용합니다.

정규표현식의 기본 구성 요소

  • 리터럴 문자: 자신을 그대로 뜻하는 문자들 예를 들어, a는 그냥 문자 a를 의미합니다.
  • 메타 문자: 특별한 의미를 가지는 문자들로, .^$*+?[]{}()| 등이 있습니다.

정규표현식에서의 중요한 메타 문자

  • .: 임의의 단일 문자를 의미합니다. 예를 들어, a.c는 a와 c 사이에 어떤 문자라도 있는 ‘a-c’ 형식을 찾습니다.
  • []: 대괄호 안에 있는 여러 문자 중 하나를 의미합니다. [abc]는 a, b 또는 c 중 하나를 찾습니다.
  • ^: 문자열의 시작을 의미합니다. 예를 들어, ^abc는 ‘abc’로 시작하는 문자열을 찾습니다.
  • $: 문자열의 끝을 의미합니다. xyz$는 ‘xyz’로 끝나는 문자열을 찾습니다.
  • *: 바로 앞의 문자가 0번 이상 반복되는 것을 의미합니다. 예를 들어, bo*는 ‘b’, ‘bo’, ‘boo’, ‘booo’ 등의 패턴을 찾습니다.
  • +: 바로 앞의 문자가 1번 이상 반복되는 것을 의미합니다. bo+는 ‘bo’, ‘boo’, ‘booo’ 등의 패턴을 찾습니다.
  • ?: 바로 앞의 문자가 0 또는 1번 나타남을 의미합니다. colou?r은 ‘color’와 ‘colour’ 모두를 찾을 수 있습니다.
  • {}: 중괄호 안의 숫자는 반복되는 회수를 지정합니다. 예를 들어, a{2}는 ‘aa’를 의미하고, a{2,3}는 ‘aa’ 또는 ‘aaa’를 의미합니다.
  • (): 그룹을 지정합니다. 이를 통해 하나의 전체 패턴을 묶거나, 캡처해서 사용할 수 있습니다.
  • |: OR 연산자로 ‘A 또는 B’를 의미합니다. a|b는 ‘a’ 또는 ‘b’를 의미합니다.

파이썬에서 정규표현식 사용하기

파이썬에서 정규표현식 기능은 re 모듈을 통해 제공됩니다. 이 모듈을 사용하여 다양한 정규표현식 패턴을 검증, 검색 및 수정할 수 있습니다.

re 모듈 기본 사용법

import re

# 정규표현식 패턴에 매칭되는지 체크
pattern = r"^abc"
string = "abcdefg"
if re.match(pattern, string):
    print("정규표현식에 매칭됩니다!")
else:
    print("매칭되지 않습니다.")
    

위의 코드에서는 ^abc라는 정규 표현식을 사용하여 문자열이 ‘abc’로 시작하는지를 확인합니다. match 함수는 문자열 시작부터 검색을 하므로, ‘abcdefg’는 ‘abc’로 시작하므로 매칭됩니다.

중첩 패턴 검색: re.search()

match()와 달리 search()는 문자열 전체에서 패턴을 찾을 수 있습니다. 예를 들어, 문자열 내 중간에 있는 패턴도 찾습니다.

import re

pattern = r"abc"
string = "xyzabcdef"

if re.search(pattern, string):
    print("패턴이 발견되었습니다!")
else:
    print("패턴이 발견되지 않았습니다.")
    

모든 패턴 찾기: re.findall()

문자열 내에서 패턴과 맞는 모든 부분을 리스트로 반환하고 싶을 때 사용합니다.

import re

pattern = r"a"
string = "banana"

matches = re.findall(pattern, string)
print(matches)
    

위의 예제에서는, 문자열 ‘banana’에서 ‘a’를 모두 찾아 리스트로 반환합니다, 결과는 [‘a’, ‘a’, ‘a’]가 됩니다.

패턴 대체하기: re.sub()

매칭되는 패턴을 다른 문자열로 대체하려면 sub() 함수를 사용합니다.

import re

pattern = r"a"
replacement = "o"
string = "banana"

new_string = re.sub(pattern, replacement, string)
print(new_string)
    

이 코드는 문자열 ‘banana’의 모든 ‘a’를 ‘o’로 변경하여 ‘bonono’라는 결과를 생성합니다.

실제 예제를 통한 정규표현식의 응용

정규표현식은 데이터 검증, 데이터 추출 및 데이터 조작에 있어 매우 효과적입니다. 여기서는 전화번호, 이메일, URL 추출과 같은 실제 예제를 통해 정규표현식의 응용을 알아보겠습니다.

1. 전화번호 추출

전화번호는 다양한 형식으로 존재할 수 있습니다. 예를 들어, ‘(123) 456-7890’, ‘123.456.7890’, ‘123-456-7890’ 등의 형식입니다. 이를 추출하는 정규 표현식을 작성해 봅시다.

import re

pattern = r"\(?\d{3}\)?[-.\s]?\d{3}[-.\s]?\d{4}"
text = "연락처: (123) 456-7890, 그리고 123-456-7890."

phone_numbers = re.findall(pattern, text)
print(phone_numbers)
    

위의 정규표현식은 다양한 형식의 전화번호를 추출할 수 있습니다.

2. 이메일 주소 검증 및 추출

이메일 주소는 일반적으로 username@domain.extension 형태로 되어 있습니다. 이를 추출하는 정규표현식은 다음과 같습니다:

import re

pattern = r"\b[A-Za-z0-9._%+-]+@[A-Za-z0-9.-]+\.[A-Z|a-z]{2,7}\b"
text = "문의사항은 contact@example.com 으로 이메일을 보내 주세요."

emails = re.findall(pattern, text)
print(emails)
    

이 정규표현식은 이메일 주소 형식을 따라 다양한 이메일 주소를 추출할 수 있습니다.

3. URL 추출

웹 페이지에서 URL 링크를 추출하는 것도 유용할 수 있습니다. 정규표현식을 사용하여 큰 텍스트에서 URL을 쉽게 검색할 수 있습니다.

import re

pattern = r"https?://(?:www\.)?\S+\.\S+"
text = "저희 웹사이트는 https://www.example.com 입니다. 링크를 방문해보세요."

urls = re.findall(pattern, text)
print(urls)
    

이 예제의 정규표현식은 HTTP 및 HTTPS로 시작하는 URL을 추출합니다. ‘www’가 있을 수도 있고 없을 수도 있으며, 도메인 이름 뒤에는 다양한 확장자가 올 수 있습니다.

정규표현식 디버깅 및 최적화

정규표현식은 매우 강력하지만, 복잡한 패턴을 작성할 때는 오류가 발생할 수 있습니다. 따라서 이를 디버깅하고 최적화하는 몇 가지 팁을 소개합니다.

주석 사용하기

정규표현식에 주석을 달면 복잡한 패턴을 이해하기 쉽게 만들 수 있습니다. 파이썬에서는 re.VERBOSE 플래그를 사용해서 주석을 추가할 수 있습니다.

import re

pattern = r"""
(?x)            # 정규표현식 레이아웃을 말하며, 주석 사용 가능
\(?\d{3}\)?    # 지역번호, 선택적 괄호
[-.\s]?         # 지역번호 뒤의 구분자
\d{3}          # 세 자리 번호
[-.\s]?         # 다음 번호 사이의 구분자
\d{4}          # 마지막 네 자리 번호
"""
text = "여기에 전화번호 (123) 456-7890 및 987-654-3210가 있습니다."
phone_numbers = re.findall(pattern, text)
print(phone_numbers)
    

효율적인 패턴 작성

  • 가능하면 단순하고 명확한 패턴을 사용하여 처리 속도를 높입니다.
  • 특정 매칭 범위를 감소시켜 검색 시간을 단축합니다.
  • 문자 클러스터를 사용하여 여러 메타문자를 축소하여 적용합니다.

결론

정규표현식은 문자열 처리를 위한 강력하고 유연한 도구입니다. 처음에는 복잡해 보일 수 있지만, 익숙해지면 데이터 검색, 검증 및 변환을 위한 탁월한 도구가 됩니다. 위의 실습 예제를 통해 실전에서 정규표현식을 어떻게 사용하는지 직접 시도해 보시길 바랍니다. 파이썬의 re 모듈을 활용하여 다양한 형태의 문자열을 효과적으로 처리할 수 있도록 연습하시기 바랍니다.

3. 텍스트 데이터에서의 정보 추출

정규 표현식은 자연어 처리(NLP)와 데이터 분석에서도 효과적으로 사용됩니다. 예를 들어, 고객 피드백 데이터에서 특정 키워드를 검색하거나 금융 데이터에서 수치 및 통화 정보를 추출하는 데 활용할 수 있습니다.

import re

# 고객 피드백 예제
feedback = "저희 은행의 서비스는 환상적이었어요. 특히 김 대리님의 친절함에 감동했습니다. 감사합니다!"

# '김 대리님'을 포함한 발화 추출
agent_pattern = r".*김 대리님.*"
agent_feedback = re.search(agent_pattern, feedback)

if agent_feedback:
    print(agent_feedback.group())  # 발생 시 특정 문장 추출

정규 표현식 사용 시 유의점

정규 표현식은 매우 강력한 도구이지만, 잘못 사용할 경우 성능상 문제가 발생할 수 있습니다. 특히 복잡한 패턴을 처리할 때는 CPU 사용량이 급증할 수 있습니다. 최적화를 위해서는 다음 사항을 유의하세요:

  • 최대한 간단한 패턴을 사용하고, 불필요한 그룹화는 피합니다.
  • 비탐욕적 매칭을 적절히 활용하여 검색 시간을 단축합니다.
  • 정규 표현식을 사용할 필요가 없는 경우, 문자열 메서드(str.find()str.replace() 등)를 사용하는 것이 좋습니다.

정규 표현식 디버깅하기

정규 표현식을 작성할 때 예상치 못한 결과가 나오는 경우가 종종 있습니다. 이를 해결하기 위해 다양한 온라인 디버깅 도구를 활용할 수 있습니다. 정규 표현식의 일치 패턴을 시각적으로 확인할 수 있어, 빠르게 문제점을 파악하고 수정할 수 있습니다.

정규 표현식의 확장 기능

파이썬의 re 모듈은 기본적인 정규 표현식 기능 외에도 플래그를 사용하여 추가적인 기능을 제공합니다. 예를 들어, 대소문자 구분을 하지 않도록 하거나, 멀티라인 문자열을 다룰 때 유용한 기능들이 있습니다:

  • re.IGNORECASE: 대소문자 구분을 무시하여 매칭합니다.
  • re.MULTILINE: 여러 줄에서 시작과 끝을 찾을 때 사용합니다.
  • re.DOTALL: 마침표(.)가 줄바꿈 문자를 포함한 모든 문자에 매칭됩니다.
import re

# 여러 줄 문자열
multiline_text = """first line
second line
third line"""

# 여러 줄에서 줄의 시작을 찾는 예
multiline_pattern = r"^second"  # 'second'로 시작하는 줄 찾기

# match 한 결과
matches = re.findall(multiline_pattern, multiline_text, re.MULTILINE)
print(matches)  # ['second']

결론

이번 강의에서는 파이썬에서 정규 표현식을 사용하는 다양한 방법들을 살펴보았습니다. 정규 표현식은 문자열 처리를 위해 매우 강력한 도구이며, 다양한 분야에서 적용할 수 있습니다. 실전 활용 예제를 통해 정규 표현식의 유용성을 체감해 보시길 바랍니다. 정규 표현식을 처음 접하는 경우 복잡하고 어렵게 느껴질 수 있지만, 패턴을 이해하고 응용하는 능력을 키우면 매우 효율적인 도구가 될 것입니다.

실습과 반복 학습을 통해 정규 표현식에 점점 익숙해지고 나면, 복잡한 문자열 처리 문제도 쉽게 해결할 수 있는 강력한 스킬을 얻게 될 것입니다. 이번 강의가 파이썬 정규 표현식의 기초를 다지는 데에 큰 도움이 되었기를 바랍니다.

더 많은 실습과 예제를 통해 정규 표현식을 친숙하게 다루어 보며, 더욱 발전된 데이터 처리 및 분석 능력을 길러보세요!

08-2 파이썬 강좌 – 정규 표현식 시작하기

정규 표현식이란?

정규 표현식은 문자열을 특정한 패턴과 일치시키기 위한 강력한 도구입니다. 주로 데이터 유효성 검사, 검색, 그리고 텍스트 처리 작업에 사용됩니다. 프로그래밍 언어들, 특히 파이썬에서 정규 표현식을 활용하면 복잡한 패턴 매칭을 쉽게 처리할 수 있습니다.

파이썬에서 정규 표현식 사용하기

파이썬의 re 모듈에서는 다양한 정규 표현식 관련 기능을 제공합니다. 주로 사용하는 함수로는 matchsearchfindallfinditer 등을 소개할 수 있습니다.


# re 모듈 임포트
import re

# 패턴 매칭 예제
pattern = re.compile(r'\d+')

# 문자열에서 숫자를 검색
match = pattern.search("비용은 1200원입니다.")
if match:
    print("숫자 발견:", match.group())
    

정규 표현식의 기본 패턴

정규 표현식에서 자주 사용되는 메타 문자들을 통해 보다 복잡한 패턴 매칭을 수행할 수 있습니다. 예를 들어:

  • . : 임의의 한 문자
  • ^ : 문자열의 시작
  • $ : 문자열의 끝
  • * : 0개 이상의 반복
  • + : 1개 이상의 반복
  • ? : 0개 또는 1개의 반복

고급 패턴 매칭

정규 표현식을 보다 깊이 있게 사용하려면, 그룹화와 캡쳐, 전방 탐색 및 후방 탐색 같은 고급 기능을 이해해야 합니다.


# 그룹화 예제
pattern = re.compile(r'(\d{3})-(\d{3,4})-(\d{4})')
match = pattern.search("전화번호는 010-1234-5678입니다.")
if match:
    print("지역 번호:", match.group(1))
    print("중간 번호:", match.group(2))
    print("마지막 번호:", match.group(3))
    

정규 표현식의 유용한 예제

정규 표현식은 다양한 문자열 패턴을 식별하고 처리하는 데 사용할 수 있습니다. 예를 들어, 이메일 주소의 유효성을 검사하거나, 텍스트에서 URL을 추출하는 등의 작업을 할 수 있습니다.

실전 예제

실무에서의 다양한 사례를 통해 정규 표현식의 응용을 살펴보겠습니다. 이 부분에서는 구체적인 코드를 통해 정규 표현식이 문제 해결에 어떻게 기여할 수 있는지를 보여줍니다.

정규 표현식을 사용할 때의 주의점

정규 표현식은 강력한 도구이지만, 때때로 성능 문제가 발생할 수 있습니다. 특히 매우 복잡한 패턴이나 대용량 데이터에 적용할 때는 주의를 기울여야 합니다. 또한, 가독성과 유지 보수성을 고려하여 사용해야 합니다.

결론

정규 표현식은 파이썬과 같은 프로그래밍 언어에서 매우 유용한 기능입니다. 충분한 연습과 이해를 통해, 코드를 보다 효율적이고 간결하게 작성할 수 있습니다.

08-1 파이썬 강좌 – 정규 표현식 살펴보기

정규 표현식이란?

정규 표현식(Regular Expressions, 줄여서 regex 또는 regexp)은 특정한 규칙에 맞는 문자열을 검색, 치환, 추출할 때 사용되는 문자열입니다. 주로 텍스트 프로세싱에서 여러 패턴을 검색하거나 데이터 유효성 검사를 위해 사용됩니다.

정규 표현식의 기본 개념

정규 표현식의 기본 개념을 이해하기 위해 일반적으로 사용되는 몇 가지 특별한 문자를 이해해야 합니다.

기본 패턴

  • 점(.): 임의의 한 문자를 나타냅니다.
  • 대괄호([]): 대괄호 안의 문자 중 하나를 나타냅니다. 예: [abc]
  • 캐럿(^): 문자열의 시작을 나타냅니다. 예: ^Hello
  • 달러 기호($): 문자열의 끝을 나타냅니다. 예: world$
  • 별표(*): 이전 문자가 0번 이상 반복되는 것을 나타냅니다. 예: a*
  • 플러스(+): 이전 문자가 1번 이상 반복되는 것을 나타냅니다. 예: a+
  • 물음표(?): 이전 문자가 0번 또는 1번 나타나는 것을 나타냅니다. 예: a?

메타 문자

메타 문자들은 정규식에서 특별한 의미로 사용되며, 종종 필요에 따라 이스케이프하여 문자 그대로 사용해야 합니다.

  • 백슬래시(\\): 이스케이프 문자로, 특수 문자를 일반 문자로 사용하기 위해 씁니다.
  • 파이프(|): OR 연산자로 여러 패턴 중 하나라도 매칭되면 참으로 간주합니다. 예: a|b
  • 괄호(()): 그룹화를 나타내며, 서브패턴을 만들 때 사용합니다. 예: (ab)

파이썬에서의 정규 표현식 사용법

파이썬에서는 `re` 모듈을 사용하여 정규 표현식을 다룹니다. 이 모듈은 다양한 함수를 제공하여 정규 표현식을 쉽게 사용할 수 있습니다.

re 모듈 함수

  • re.match(): 문자열의 시작 부분이 지정한 패턴과 매칭되는지 확인합니다.
  • re.search(): 문자열 전체를 검색하여 첫 번째 매칭되는 패턴을 찾습니다.
  • re.findall(): 패턴과 매칭되는 모든 부분 문자열을 리스트로 반환합니다.
  • re.finditer(): 패턴과 매칭되는 모든 부분 문자열을 순환 가능한 객체로 반환합니다.
  • re.sub(): 패턴과 매칭되는 부분 문자열을 다른 문자열로 치환합니다.

정규 표현식 사용 예제

기본 사용 예시


import re

# 문자열의 시작이 'Hello'인지 확인
result = re.match(r'^Hello', 'Hello, world!')
print(result)  # 매칭에 성공하면 매치 객체를 반환하고, 실패하면 None을 반환합니다.
    

문자열 내 패턴 찾기


import re

search_result = re.search(r'world', 'Hello, world!')
print(search_result)  # 매칭된 부분에 대한 매치 객체를 반환합니다.
    

모든 매칭 패턴 추출


# 문자열에서 모든 'a' 문자 찾기
all_matches = re.findall(r'a', 'banana')
print(all_matches)  # 찾은 모든 매칭의 리스트가 반환됩니다.
    

패턴을 기반으로 문자열 변환하기

re.sub() 함수를 사용하여 문자열 내 패턴을 다른 문자열로 변환할 수 있습니다.


# 모든 공백을 언더스코어로 교체
transformed_string = re.sub(r'\s', '_', 'Hello world!')
print(transformed_string)  # 'Hello_world!' 출력
    

고급 정규 표현식 기능

그룹과 캡처링

그룹화는 정규식의 서브패턴을 캡처하고 재사용하거나 특정 작업을 수행하는 데 매우 유용합니다.


pattern = r'(\d+)-(\d+)-(\d+)'
string = '전화번호: 123-456-7890'
match = re.search(pattern, string)

if match:
    print(match.group(0))  # 전체 매칭된 문자열
    print(match.group(1))  # 첫 번째 그룹: 123
    print(match.group(2))  # 두 번째 그룹: 456
    print(match.group(3))  # 세 번째 그룹: 789
    

Lookahead 및 Lookbehind

Lookahead와 Lookbehind는 특정 패턴 앞 또는 뒤에 있는 조건을 검사할 때 사용합니다. 이러한 기능은 흔히 사용되는 기술이지만 다소 복잡할 수 있습니다.

Lookahead 사용


# 'abc' 뒤에 'def'가 오는 패턴 찾기
lookahead_pattern = r'abc(?=def)'
lookahead_string = 'abcdefghi'
lookahead_match = re.search(lookahead_pattern, lookahead_string)
print(lookahead_match)
    

Lookbehind 사용


# '123' 앞에 오는 패턴
lookbehind_pattern = r'(?<=123)abc'
lookbehind_string = '123abc'
lookbehind_match = re.search(lookbehind_pattern, lookbehind_string)
print(lookbehind_match)
    

종합 예제: 이메일 주소 추출

정규 표현식은 특히 입력된 텍스트에서 이메일 주소를 추출하는 데 유용합니다.


email_pattern = r'[a-zA-Z0-9._%+-]+@[a-zA-Z0-9.-]+\.[a-zA-Z]{2,}'
text = "연락처 이메일: example@example.com 또는 support@domain.com"
emails = re.findall(email_pattern, text)

print(emails)  # ['example@example.com', 'support@domain.com']
    

정리

정규 표현식은 문자열 처리에서 매우 강력한 도구이며, 파이썬의 `re` 모듈은 이를 다루기에 충분한 기능을 제공합니다. 정규 표현식의 기본 문법을 이해하고 실습하면 복잡한 텍스트 패턴을 손쉽게 다룰 수 있습니다. 이러한 기술을 꾸준히 연습하고 활용하면 더욱 복잡한 문자열 처리 문제를 효과적으로 해결할 수 있을 것입니다.

07장: 파이썬 날아오르기

이 강좌에서는 파이썬의 고급 기능을 활용하여 복잡한 문제를 해결하고 효율적인 코드를 작성하는 방법에 대해 알아보겠습니다. 우리가 다루게 될 주요 주제들은 다양한 프로그래밍 패러다임, 고급 데이터 구조, 그리고 파이썬이 제공하는 강력한 내장 모듈 기능들을 포함합니다.

1. 고급 프로그래밍 패러다임

파이썬은 다중 패러다임 프로그래밍 언어입니다. 프로시저형, 객체 지향, 함수형 프로그래밍을 지원하며, 필요에 따라 각각의 장점을 취할 수 있습니다. 이번 장에서는 주로 객체 지향 프로그래밍(OOP)과 함수형 프로그래밍의 고급 기법에 대해 다루겠습니다.

1.1 객체 지향 프로그래밍 심화

OOP의 기본적인 개념은 클래스와 객체의 이해에서 출발합니다. 그러나 보다 복잡한 프로그램을 설계하기 위해서는 다른 개념도 알아야 합니다.

1.1.1 상속과 폴리모르피즘

상속은 새로운 클래스가 기존의 클래스의 속성과 메서드를 물려받는 기능입니다. 상속을 통해 코드의 재사용성을 높일 수 있습니다. 폴리모르피즘은 다른 클래스의 객체들에 대해 동일한 인터페이스를 사용할 수 있게 해줍니다.

class Animal:
    def speak(self):
        pass

class Dog(Animal):
    def speak(self):
        return "Woof!"

class Cat(Animal):
    def speak(self):
        return "Meow!"

def animal_sound(animal):
    print(animal.speak())

dog = Dog()
cat = Cat()

animal_sound(dog)  # Woof!
animal_sound(cat)  # Meow!

위 예제는 폴리모르피즘의 예시입니다. 각기 다른 클래스의 객체들이 speak() 메서드를 가짐으로써, animal_sound 함수에서 동일한 방식으로 호출이 가능합니다.

1.1.2 추상화와 인터페이스

추상 클래스는 기본 동작을 정의하는 클래스이며, 하나 이상의 추상 메서드를 가집니다. 인터페이스는 이러한 추상 메서드의 집합으로 생각할 수 있습니다. 파이썬에서는 abc 모듈의 ABC 클래스를 통해 추상화를 구현합니다.

from abc import ABC, abstractmethod

class Shape(ABC):
    @abstractmethod
    def area(self):
        pass

class Circle(Shape):
    def __init__(self, radius):
        self.radius = radius

    def area(self):
        return 3.1415 * self.radius * self.radius

circle = Circle(5)
print(circle.area())  # 78.5375

위 예제에서 Shape 클래스는 추상 클래스로써, area라는 추상 메서드를 정의합니다. Circle 클래스는 Shape를 상속받아 area 메서드를 구체화합니다.

1.2 함수형 프로그래밍

함수형 프로그래밍은 순수 함수를 사용하여 부작용을 줄이고, 함수 합성을 통해 복잡한 동작을 구현합니다. 파이썬은 이러한 스타일을 장려하기 위해 강력한 함수형 도구를 제공합니다.

1.2.1 람다 함수

람다 함수는 익명의 함수로, 보통 한 줄의 표현식으로 정의됩니다. 짧고 간결한 함수를 작성할 때 유용합니다.

add = lambda x, y: x + y
print(add(5, 3))  # 8

위의 예제에서 lambda는 두 매개변수를 더하는 익명 함수를 정의합니다.

1.2.2 고차 함수

고차 함수는 함수 자체를 인자로 받거나 반환하는 함수입니다. 파이썬의 mapfilterreduce는 이런 함수형 프로그래밍 기법을 활용한 예입니다.

numbers = [1, 2, 3, 4, 5]
squared = map(lambda x: x**2, numbers)
print(list(squared))  # [1, 4, 9, 16, 25]

위의 예제에서 map 함수는 각 리스트 요소에 람다 함수를 적용하여 새로운 이터레이터를 만듭니다.

2. 고급 데이터 구조

고급 데이터 구조 활용은 복잡한 데이터 작업을 보다 효율적으로 수행할 수 있게 합니다. 여기서는 리스트, 딕셔너리 같은 기본 자료형을 넘어, 더 복잡한 데이터 구조를 다룹니다.

2.1 컬렉션 모듈

파이썬의 collections 모듈은 특별한 목적을 가진 여러 데이터 구조를 제공합니다. 그 중 몇 가지를 살펴보겠습니다.

2.1.1 defaultdict

defaultdict는 존재하지 않는 키를 참조할 때 자동으로 기본값을 생성하는 딕셔너리입니다.

from collections import defaultdict

fruit_counter = defaultdict(int)
fruits = ['apple', 'banana', 'apple', 'orange', 'banana', 'apple']

for fruit in fruits:
    fruit_counter[fruit] += 1

print(fruit_counter)  # defaultdict(, {'apple': 3, 'banana': 2, 'orange': 1})

이 예제에서는 defaultdict를 사용하여 각 과일의 개수를 쉽게 셀 수 있습니다.

2.1.2 namedtuple

namedtuple은 튜플과 같이 불변하지만, 필드를 이름으로 액세스할 수 있어 코드의 가독성을 높여줍니다.

from collections import namedtuple

Point = namedtuple('Point', ['x', 'y'])
p = Point(10, 20)

print(p.x, p.y)  # 10 20

이처럼 namedtuple을 사용해 필드를 이름으로 접근할 수 있어 명확한 코드를 작성할 수 있습니다.

2.2 힙 큐 모듈

heapq 모듈은 힙 큐 알고리즘을 구현하여, 리스트를 우선순위 큐로 사용할 수 있도록 합니다.

import heapq

numbers = [1, 3, 5, 7, 9, 2, 4, 6, 8, 0]
heapq.heapify(numbers)  # 리스트를 우선순위 큐로 변환

smallest = heapq.heappop(numbers)
print(smallest)  # 0

우선순위 큐를 사용하여 데이터의 최솟값을 빠르게 추출할 수 있습니다.

3. 고급 내장 모듈 활용

파이썬의 풍부한 내장 모듈은 다양한 기능을 제공합니다. 여기서는 고급 작업을 위한 몇 가지 모듈을 소개하겠습니다.

3.1 itertools 모듈

itertools 모듈은 반복자를 다루기 위한 유용한 함수를 제공합니다. 반복적인 데이터 처리에 강력한 도구입니다.

3.1.1 combinations와 permutations

조합과 순열은 데이터 집합에서 요소를 선택하는 다양한 방법을 제공합니다.

from itertools import combinations, permutations

data = ['A', 'B', 'C']

# 조합
print(list(combinations(data, 2)))  # [('A', 'B'), ('A', 'C'), ('B', 'C')]

# 순열
print(list(permutations(data, 2)))  # [('A', 'B'), ('A', 'C'), ('B', 'A'), ('B', 'C'), ('C', 'A'), ('C', 'B')]

이러한 기능을 통해 다양한 목록 조합을 빠르게 생성할 수 있습니다.

3.1.2 반복기 집합 다루기

무한 반복, 카운트 증가, 주기 반복 등 다양한 반복 동안 유용하게 사용할 수 있는 도구를 제공합니다.

from itertools import count, cycle

# 무한 카운트
for i in count(10):
    if i > 15:
        break
    print(i, end=' ')  # 10 11 12 13 14 15

print()  # 새로운 줄

# 주기적 반복
for i, char in zip(range(10), cycle('ABC')):
    print(char, end=' ')  # A B C A B C A B C A

위 예제는 무한루프와 주기반복의 활용방법을 보여줍니다.

3.2 functools 모듈

functools 모듈은 함수형 프로그래밍 도구를 제공합니다. 특히 함수를 다루는 데 유용한 다양한 도구들을 제공합니다.

3.2.1 lru_cache 데코레이터

@lru_cache 데코레이터는 메모이제이션을 위해 사용되며, 계산된 결과를 저장하여 같은 인풋에 대한 재계산을 피합니다.

from functools import lru_cache

@lru_cache(maxsize=None)
def fibonacci(n):
    if n <= 1:
        return n
    return fibonacci(n-1) + fibonacci(n-2)

print([fibonacci(n) for n in range(10)])  # [0, 1, 1, 2, 3, 5, 8, 13, 21, 34]

위의 코드에서, 피보나치 수열에 대한 계산 결과가 캐시에 저장되어, 동일한 인풋에 대해 수행시간을 절약할 수 있습니다.

마무리

이 글에서는 파이썬의 고급 주제에 대해 알아보았습니다. 이러한 기능들을 잘 활용하면 복잡한 문제를 효율적으로 해결하고 높은 수준의 코드를 작성할 수 있습니다. 다음 강좌에서 더욱 많은 주제를 다루며 파이썬 전문가로 나아가 보겠습니다.