230816 TIL

요시롱·2023년 8월 16일

TIL

목록 보기
5/8
post-thumbnail

Python 복습

함수, 정규표현식
새롭게 알게된 것, 자주 헷갈리는 것 위주로 정리


Parameter와 Argument

  • Parameter : 매개 변수. 함수나 메소드를 정의할 때 사용되는 변수명(variable)이다.
  • Argument : 전달 인자, 인자. 함수나 메소드에 입력되는 값(value)이다.
    • positional argument : 함수에서 정의된 순서대로 ,로 구분하여 받는 인자.
    • keyword argument : parameter 이름과 함께 받는 인자.
def divisor(num, d):
    if num % d == 0:
        return True

divisor(6, 3)            # 6과 3은 positional argument
divisor(num = 6, d = 3)  # 6과 3은 keyword argument

*args**kwargs

  • args(arguments)와 kwargs(keyword arguments)는 관습적으로 붙이는 단어로, ***의 차이이다.

  • 몇 개의 argument를 받을 지 정할 수 없을 때 *args**kwargs를 파라미터로 사용한다.

  • *는 여러 개의 positional arguments를 하나의 튜플로 묶어준다.

  • **는 여러 개의 keyword arguments를 하나의 딕셔너리로 묶어준다.

  • *args**kwargs를 동시에 사용할 경우

    • 반드시 **kwargs를 먼저 써야 한다.
  • 기본 값이 있는 keyword argument와 **kwargs를 동시에 사용할 경우

    • 반드시 기본 값이 있는 keyword argument를 먼저 써야 한다.
def test(*args, a = 1, b = 2, **kwargs)
    pass

참고 자료 : Positional argument & Keyword arguments

참고 자료 : *args 와 **kwargs 가 뭐예요?

파이썬의 내장함수

  • abs(x) : x의 절대값을 반환한다.

  • dir(x) : 객체 x가 가지고 있는 변수나 메소드 목록을 반환한다.

  • eval(x) : 실행 가능한 문자열 x를 받아 그 문자열을 실행한 결과를 반환한다.

print(eval('3 * 4')) # 12
# '3 * 4'는 문자열이지만, 문자열 내부의 내용이 실행 가능한 형태이다. 
  • filter(func, x) : 함수 func에 x를 매개변수로 전달하여 True인 경우만 반환한다.
    • filter의 첫번째 인자 함수는 True나 False를 반환하는 함수여야 한다.
def even(x):
    if x % 2 == 0:
        return True
        
num_list = [1, 2, 3, 4, 5, 6]
print(filter(even, num_list))        # <filter object at 0x000001D2770C8DC0>
print(list(filter(even, num_list)))  # [2, 4, 6, 8]

# 매개변수로 들어가는 함수를 람다함수로 작성할 수도 있다. 
print(list(filter( lambda x : x % 2 == 0, num_list)))
  • map(func, x) : 함수 func에 iterable한 x의 요소를 하나씩 전달하여 얻은 값을 묶어 반환한다.

  • isinstance(x, y) : x가 y의 인스턴스라면 True를 반환한다.

  • pow(x, y) : x의 y제곱을 반환한다.

id(int)

  • 이게 대체 무슨 말인가...싶지만 오타인지 내가 모르는 것인지 확인하면서 이런저런 값들을 찍어보다가 알게됨
num1 = 10
num2 = 'a'
print(num1 is int)          # False 객체 위치가 다르니 당연함
print(num2 is int)          # False 객체 위치가 다르니 당연함
print('------------------')
print(num1 == int)          # False 값이 다르니 당연함
print(num2 == int)          # False 값이 다르니 당연함
print('------------------')
print(type(num1) is int)    # True
print(type(num2) is int)    # False
print(id(type(num1)))       # 140705952322288
print(id(type(num2)))       # 140705952348544
print(id(int))              # 140705952322288
print(id(str))              # 140705952348544

# 즉, type(num1)과 int의 메모리 주소가 동일하므로, == 대신 int를 써도 된다. 

print('------------------')
print(type(num1) == int)    # True   보통은 이렇게 씀
print(type(num2) == int)    # False
print('------------------')
print(type(int))            # type
print(int)                  # int
print(id(int))              # 140705952322288

정규표현식

  • 특정한 규칙을 가진 문자열의 집합을 표현할 때 사용하는 형식 언어
# 정규식으로 특정 문자열에 포함된 휴대폰 번호 끝 4자리를 xxxx로 변경하자.
phone_numbers = '김철수: 010-0000-1111 박영희: 010-2222-3333'

import re
# 1번
re.sub('(\d{3}[-]\d{4})[-]\d{4}', '\g<1>-xxxx' , phone_numbers)
# \d+ : 1글자 이상
# 소괄호 : 그룹(g)
# ( \d{3} 글자 3자리 [-] \d{4} 글자 4자리) [-] \d{4} 글자 4자리  => 이런 패턴에서
# 첫번째 그룹 \g<1> 뒤를 -xxxx로 바꿔라.

# 2번
pat = re.compile('(\d{3}[-]\d{4})[-]\d{4}') # 특정한 패턴으로 컴파일
pat.sub('\g<1>-xxxx', phone_numbers)

# 김철수: 010-0000-xxxx 박영희: 010-2222-xxxx

정규표현식 메소드

<특정 문자 / 문자열 포함 여부 확인>

string = 'Hello World.'
  • match(x, str) : str의 가장 첫 번째에 x가 위치하는지 확인
re.match('H', string) # True
re.match('l', string) # False, 아무 것도 안 나옴
  • search(x, str) : str 내부의 x 중 첫 번째 x의 위치를 반환
re.search('l', string)

result = re.search('l', string)  # True
# group() : 찾은 문자열을 반환
print(result.group())  # l

# start, end, span : 찾은 문자열의 시작, 끝, 시작~끝(튜플) 인덱스를 반환
print(result.start())  # 2
print(result.end())    # 3
print(result.span())   # (2, 3)
  • findall(x, str) : str 내부의 모든 x를 리스트로 반환
print(re.findall('l', string))    # ['l', 'l', 'l']
print(re.findall('Wor', string))  # ['Wor']
  • finditer(x, str) : str 내부의 모든 x의 위치를 iterable한 객체로 반환
result = re.finditer('l', string)
for s in result:
    print(s)
    
    # <re.Match object; span=(2, 3), match='l'>
    # <re.Match object; span=(3, 4), match='l'>
    # <re.Match object; span=(9, 10), match='l'>

<여러 문자의 포함 여부 확인>

  • 확인하고 싶은 문자를 리스트에 넣어 포함 여부를 확인한다.
string = 'Hello World'
re.findall('[elo]', string)  # 모든 e, l, o를 찾는다. 
                             # ['e', 'l', 'l', 'o', 'o', 'l']
re.findall('[^elo]', string) # e, l, o 이외의 문자를 찾는다. 
                             # ['H', ' ', 'W', 'r', 'd']
  • set을 이용하면 중복을 삭제할 수 있다.

  • -를 사용하여 확인하고 싶은 알파벳이나 숫자 범위를 지정할 수 있다.

string = 'Hello World'
re.findall('[a-p]', string)       # a부터 p까지의 알파벳 중 포함된 것을 찾는다. 
                                  # ['e', 'l', 'l', 'o', 'o', 'l', 'd']
re.findall('[a-pA-P]', string)    # a ~ p, A ~ P 알파벳 중 포함된 것을 찾는다.
                                  # ['H', 'e', 'l', 'l', 'o', 'o', 'l', 'd']
re.findall('[^a-pA-P]', string)   # a ~ p, A ~ P가 아닌 것을 찾는다. 
                                  # [' ', 'W', 'r']

string = '2023 August 16'
re.findall('[0-5]', string)       # 0~5 사이의 숫자를 찾는다. 
                                  # ['2', '0', '2', '3', '1']

<두 문자 사이 문자의 포함 여부 확인>

  • Dot(.)\n을 제외한 모든 문자 1개와 매치된다.
string = 'Hello World'
re.findall('e.o', string)   # e와 o 사이에 문자 1개가 있는 문자열
                            # 없음 []
re.findall('e..o', string)  # e와 o 사이에 문자 2개가 있는 문자열
                            # ['ello'] 

<문자의 반복 확인>

string = 'grvy grovy groovy grooovy groooovy grooooovy'

# o가 0회 이상 반복됨 : *
re.findall('gro*vy', string)
# ['grvy', 'grovy', 'groovy', 'grooovy', 'groooovy', 'grooooovy']

# o가 1회 이상 반복됨 : +
re.findall('gro+vy', string)
# ['grovy', 'groovy', 'grooovy', 'groooovy', 'grooooovy']

# o가 n회 반복됨 : {n}
re.findall('gro{3}vy', string)
# ['grooovy']

# o가 m~n회 반복됨 : {m,n}
re.findall('gro{2,4}vy', string)
#['groovy', 'grooovy', 'groooovy']

# o가 0회 혹은 1회 반복됨 : ? (있거나 없거나)
re.findall('gro?vy', string)
# ['grvy', 'grovy']

1개의 댓글

comment-user-thumbnail
2023년 8월 16일

유익한 자료 감사합니다.

답글 달기