스터디/파이썬 스터디 강의자료

[3팀/김경은] 6차시 파이썬 스터디 - 문자열

경은 2023. 5. 2. 01:47

데이터 과학을 위한 파이썬 프로그래밍 교재를 사용하여 작성한 강의자료입니다.

6차시_문자열_강의안.pdf
1.06MB
6차시_문자열_과제.pdf
1.04MB

문자열의 개념

  • 문자열은 애플리케이션을 만들거나 데이터를 분석할 때 매우 중요하게 다루어지는 자료형 중 하나이다.
  • 문자열은 시퀀스 자료형이다.
  • 시퀀스 자료형 : 리스트와 같이 데이터를 순차적으로 메모리에 저장하는 형식의 데이터

시퀀스 자료형

문자열과 메모리 공간

  • 문자열을 저장하기 위해 영문자 한 글자당 1바이트의 메모리 공간을 사용
  • 컴퓨터는 이진수만 사용하므로 컴퓨터가 숫자를 인식하는 최소 단위는 1비트(bit)
  • 1비트는 0과 1만을 표현할 수 있는 크기
  • 1 바이트 (byte) = 8비트 , 2의 8승 크기인 256까지 숫자 저장 가능
>>> import sys      #sys 모듈을 호출
>>> print(sys.getsizeof("a"), sys.getsizeof("ab"), sys.getsizeof("abc"))
50 51 52            #"a", "ab", "abc" 각각의 메모리 크기 출력
  • sys.getsizeof는 특정 변수(또는 값)의 메모리 공간을 측정하는 함수로, a, ab. abc의 메모리 크기가 각각 50, 51. 52로 1씩 증가하는 것을 알 수 있음
  • 위 코드의 결과는 컴퓨터마다 다를 수 있다. 여기서 50이라는 숫자는 50바이트를 뜻함
  • 하나의 문자를 저장하기 위해 저장되는 문자 자체를 제외하고도 그 변수와 관련된 여러 가지 정보, 즉 변수의 저장 위치 등을 위해 49바이트가 필요한 것

컴퓨터가 1바이트로 문자를 저장할 수 있는 이유와 텍스트 저장 방법

  • 컴퓨터는 문자를 직접 인식하지 않는다. 컴퓨터에 a라고 알려줘도 컴퓨터는 정확히 2라는 텍스트로 인식하는 것이 아니라 컴퓨터는 이 정보를 이진수로 변환하여 저장
  • 문자가 1바이트라고 하였으니. 2의 8승의 공간에 문자에 대한 정보를 저장하는 것
  • 예를 들어, a를 저장한다고 하면 01001011 처럼 변환되어 메모리에 저장된다. 우리 눈에는 2라고 보이지만 컴퓨터 메모리와 CPU에는 01001011과 같은 숫자들이 처리되고 있음

이진수로 변환되는 표준규칙

  • 표준 규칙은 언어별, 나라별로 매우 많은데 대표적인 규칙으로 A SCIl Anercan standard code for Information Interchange 가 있고, 윈도에서 한글 처리를 위해 많이 쓰는 CP949 또는MS949, UTF-3 등이 있음
  • 이러한 규칙을 인코딩 cncoding 이라고 함

① 컴퓨터는 문자를 직접 인식하지 못한다.

② 컴퓨터는 문자를 숫자로 변환하여 인식한다.

③ 사람들은 문자를 숫자로 변환하기 위한 규칙을 만들었다.

④ 일반적으로 이 규칙은 1개의 영문자를 1바이트. 즉 2의 8승 정도의 공간에 저장한다.

  • 이러한 규칙을 이용하여 숫자와 문자를 맵핑하는 것이 바로 운영체제와 인터프리터의 역할 중 하나

문자열의 인덱싱

  • 리스트처럼 글자 하나하나가 상대적인 주소를 가지는데, 이 주소를 이용해 저장된 값을 가져오는 인덱싱이 가능

실제코드

>>> a = "abcde"
>>> print(a[0], a[4])
a e
>>> print(a[-1], a[-5])
e a

a[0] → a의 0번째 값으로 a 출력

a[4] → a의 4번째 값으로 e 출력

  • 역순 인덱싱
  • 오른쪽부터 -1로 시작하여 -5까지 주소가 변함

문자열의 슬라이싱

  • 슬라이싱은 문자열의 주소값을 이용해 문자열의 부분값을 추출해내는 기법
>>> a = "TEAMLAB MOOC, AWESOME Python"
>>> print (a[0:6], "AND", a[-9:1])     #a 변수의 0부터 5까지, -9부터 끝까지
TEAMLA AND ME Python
>>> print(a[:])                        #a 변수의 처음부터 끝까지
TEAMLAB MOOC, AWESOME Python
>>> print (a[-50:50])                  #범위를 넘어갈 경우 자동으로 최대 볌위를 지정
TEAMLAB MOOC, AWESOME Python
>>> print(a[::2], "AND", a[::-11)
TALBMO,AEOEPto AND nohtyP EMOSEWA ,COOM BALMAET
  • a[0:6] → 0번째 인덱스부터 5번째 인덱스까지
  • a[-9:] → -9번째 인덱스부터 끝까지
  • a[::2] → 처음부터 끝까지 두 글자씩 띄어서 출력
  • a[::-1] → 글자의 역순으로 출력

문자열 슬라이싱 기법은 리스트 슬라이싱과 사용법이 완전히 같음

💡 변수[시작 인덱스:종료 인덱스:증가값]

 

문자열의 연산

  • 변수와 마찬가지로 연산이 가능하고 문자열의 연산은 리스트 연산과 같음
>>> a = "TEAM"
>>> b = "LAB"
>>> print(a + " " + b)                   # 덧셈으로 a와 b 변수 연결하기
TEAM LAB
>>> print(a * 2 + " " + b * 2)           # 곱하기로 반복 연산 가능
TEAMTEAM LABLAB
>>> if 'A' in a: print(a)                # 'A'가 a에 포함되었는지 확인
        else: print (b)

TEAM
  • 덧셈 연산은 모든 변수가 문자열일 경우 텍스트 붙이기가 이루어짐
  • a * 2 → a+a 의 연산으로 같은 글자가 두번 출력됨
  • in 연산 → if 문과 흔히 사용하여 특정 문자가 특정 변수에 들어있는지 확인하는 연산

print() 함수에서 정수형과 문자열을 같이 보여주려고 할때 하는 실수

>>> int_value = 2
>>> print("결과는"+int_value)

문자열 함수

💡 변수.함수명

>>> title = "TEAMLAB X Inflearn"
>>> title.upper ()                  # title 변수를 모두 대문자로 변환
'TEAMLAB X INFLEARN'
>>> title.lower ()                  # title 변수를 모두 소문자로 변환
'teamlab x inflearn'
  • upper () 함수
  • 문자열을 대문자로 변환
  • lower() 함수
  • 문자열을 소문자로 변환
>>> title = "TEAMLAB X Inflearn"
>>> title.title()                   # title 변수의 각 단어의 앞글자만 대문자로 변환
'Teamlab X Inflearn'
>>> title.capitalize ()             # title 변수의 첫 번째 글자만 대문자로 변환
'Teamlab x inflearn'
  • title () 함수
  • 각 단어의 앞글자만 대문자로 바꾸는 함수
  • capitalize() 함수
  • 첫 번째 글자만 대문자로 바꾸는 함수
>>> title = "TEAMLAB X Inflearn"
>>> title.count ("a")        # title 변수에 'a'가 몇 개 있는지 개수 반환
1
>>> title.upper().count("a") # title 변수를 대문자로 만든 후, 'a'가 몇 개 있는지 개수 반환
0
>>> title.isdigit()          # title 변수의 문자열이 숫자인지 여부 반환
False
»> title.startswith("a")     # title 변수가 'a'로 시작하는지 여부 반환
False

split() 함수

특정 값을 기준으로 문자열을 분리하여 리스트 형태로 변환

>>> items = 'zero one two three'.split()  # 빈칸을 기준으로 문자열 분리하기
>>> print (items)
['zero', 'one', 'two', 'three']
  • 문자열 zero one two three'를 split( ) 함수를 사용하여 리스트형의 변수로 변환한다.
  • split( ) 함수 안에 매개변수로 아무것도 입력하지 않으면 빈칸을 기준으로 문자열을 분리하라는 뜻이다. split() 함수는 텍스트를 리스트 형태로 간단히 나누어 분리할 수 있다는 점에서 널리 사용되고 있다.

split( ) 함수에 매개변수를 넣어 텍스트를 분리하는 방법

>>> example = 'python,jquery ‚javascript'   #","를 기준으로 문자열 나누기
>>> example.split(",")
['python', 'jquery', 'javascript']
>>> a, b, c = example.split(",")  # 리스트에 있는 각 값을 a, b, c 변수로 언패킹
>>> print(a, b, c)
python jquery javascript
>>> example = 'theteamlab.univ.edu'
>>> subdomain, domain, tld = example.split('.') 
#""을 기준으로 문자열 나누기 - 언패킹
>>> print (subdomain, domain, tld) 
theteamlab univ edu
  • 문자열이 콤마(,)를 기준으로 묶여있다. split(",")를 사용하면 콤마를 기준으로 문자열을 분리할 수 있다.
  • split(".")을 사용하면 점(.)을 기준으로 분리한다. 또한, split() 함수는 a, b, c = example.split(",")와 같이 결과값을 바로 언패킹하여 사용할 수도 있다.
  • theteamlab.univ.edu와 같은 도메인 네임을 의미별로 분리할 때도 split( ) 함수를 이용한다.

join() 함수

문자열로 구성된 리스트를 합쳐 하나의 문자열로 만들 때 사용한다.

join() 함수는 구분자.join(리스트형) 형태

>>> colors = ['red', 'blue', 'green', 'yellow']
>>> result = ''.join (colors)
>>> result
'redbluegreenyellow'
  • colors 변수에 join() 함수를 적용하면 각각의 색이름이 하나의 문자열 값으로 반환된다.
  • 만약 색이름 사이에 다양한 구분자를 넣고 싶다면 join() 함수 앞에 ‘·'나'-' 등을 추가하면 된다.

다양한 구분자를 삽입한 예

>>> result = ''.join (colors)           # 연결 시, 1칸을 띄고 연결
>>> result
'red blue green yellow'
>>> result = ','.join (colors)          # 연결 시 ", "로 연결
>>> result
'red, blue, green, yellow'
>>> result = '-'.join (colors)          # 연결 시 "-"로 연결
>>> result
'red-blue-green-yellow'

문자열 표현과 특수문자

  • 문자열로 표현하기 어려운 경우

줄바꿈

It's Ok.
I'm Happy.
See you.

문자열 자체에 작은따옴표나 큰따옴표가 들어가 있는 경우

a = "It's Ok."
  • 작은 따옴표가 들어간 문자열은 큰따옴표로 선언하고, 큰따옴표가 들어간 문자열은 작은따옴표로 선언

파이썬 특수문자 기능

  • 아포스트로피(’) 문자 사용
a = 'It\\'s Ok.'
  • 두 줄 이상의 표현
a = """
It's Ok.
I'm Happy.
See you. """

문자열 서식 지정

  • 서식 지정은 print () 함수를 사용하여 형식을 통일하여 문자열을 출력할 때 유용
  • 서식 지정의 개념
    • print() 함수는 기본적으로 변수 또는 값을 콤마(,)로 띄어쓰기 하여 출력하지만 print() 함수를 사용하다 보면 특정한 형식에 맞추어 결과를 출력해야 하는 경우도 발생한다.
    • 특히 엑셀을 사용할 때 통화 단위, 세 자리 숫자 단위로 띄어쓰기, % 출력 등 다양한 형식에 맞추어 출력할 일이 생기는데, 이를 서식 지정 (formating) 이라고 한다.
  • % 서식과 format() 함수
    • 문자열의 서식을 설정할 때 print() 함수는 기본적인 출력 외에 %서식과 format() 함수를 구문으로 사용하여 출력 양식 지정 가능
    print(1, 2, 3)
    print("a" + "" + "b" + "" + "c")
    print("%d %d %d" % (1, 2, 3))
    print("{} {} {}".format("a", "b", "c"))
    
    #출력 결과
    
    1 2 3
    a b c
    1 2 3
    a b c
    
    1. 1~2행은 별도의 서식 지정 없이 그대로 print() 함수를 사용하였고. 3~4행은 % 서식 지정 과 format() 함수를 사용하였다.
    2. 3~4행과 같은 구문을 사 용할 경우 뒤에 있는 숫자와 문자들이 앞의 서식 지정 코드에 대응되어 할당된다. 즉, 3행의 "%d %d %d % (1, 2, 3)에서 1, 2, 3이 각각 첫 %d부터 차례로 대응되어 할당된다.
    3. 4행에서도 "{} {} {}".format("a", "b", “c")에서 아무것도 적혀있지 않은 {} 공간에 "a”, "b” "c"라는 문자열 형태의 값 3개가 각각 대응되어 출력된다.
    이런 식으로 서식을 지정하여 출력하는 장점
    1. 데이터와 출력 형식을 분류 할 수 있다. 같은 내용을 여러 번 반복하기 위해 기존 print() 문에 스페이스바를 이용해 띄어쓰기를 넣어 + 기호로 문자열 형태를 붙여주는 것보다 시각적으로 훨씬 이해하기 쉽게 코드를 작성 가능하다.
    2. 데이터를 형식에 따라 다르게 표현할 수 있다. 아래 코드를 보면 문자열 형태인 (’one’, ‘two’) 구문과 정수형인 (1, 2) 구문이 각각 %s와 %d로 다르게 지정되어 있다. 서식 지정 기능은 각 변수의 자료형에 맞게 서로 다르게 지정할 수 있다.
    print('%s %s' %('one','two'))
    print('%d %d'%(1,2))
    
    #출력 결과
    
    one two
    1 2
    
    • % 서식
    💡 ‘%자료형%(값)’
    print("I eat %d apples."%3)
    print("I eat %s apples."%"five")
    
    #실행 결과
    
    I eat 3 apples.
    I eat five apples.
    
    • %d
    • 정수형의 변수를 할당
    • %s
    • 문자열의 변수를 할당
    변수의 자료형에 따른 서식서식 설명
    %s 문자열(string)
    %c 문자 1개 (character)
    %d 정수 (integer)
    %f 실수 (floating-point)
    %o 8진수
    %x 16진수
    %% 문자 % 자체
    %에 1개 이상의 값도 할당 가능
>>> print("Product: %, Price per unit: %f."% ("Apple", 5.243))
Product: Apple, Price per unit: 5.243000.

변수명을 넣어서도 실행 가능

number = 3
day = "three"
print("I ate % apples. I was sick for % days." % (number, day))
#실행 결과

I ate 3 apples. I was sick for three days.
  • 3과 three 가 각각 첫번째 자리 %d와 두 번째 자리 %s에 들어감

format() 함수

%서식과 사용법이 거의 같지만 문자열 형태의 인수를 사용한다는 차이점이 있음

💡 “{자료형}”.format(인수)

>>> print("I'm {0} years old.".format(20))
I'm 20 years old.
  • 숫자 20이 {0}에 할당되어 출력
  • 기존 % 서식과 비교하여 자료형을 바로 지정해주지 않고 순서대로 변수가 할당
age = 40; name = 'Sungchul Choi'
print("I'm {0} years old.". format (age))
print ("My name is {0} and (1} years old.". format (name, age))
print("Product: {0}, Price per unit: {1:.2f}.".format ("Apple", 5.243))
#출력 결과

I'm 40 years old.
My name is Sungchul Choi and 40 years old.
Product: Apple, Price per unit: 5.24.
  • % 서식처럼 변수의 이름을 사용하거나 변수의 자료형을 따로 지정하여 출력
  • Price per unit: {1:.2f}에서 기존 format() 함수와 다르게 .2f 라는 구문이 추가되었다. 이 코드는 % 서식에서 실수형을 표현하는 기법과 같으며 .2는 소수점 둘째 자리까지 출력하라는 뜻

패딩

  • 파이썬 서식 지정 기능에는 여유 공간을 지정하여 글자 배열을 맞추고 소수점 자릿수를 맞추는 패딩 기능이 있음
  • % 서식과 format() 함수 모두 패딩 기능 제공

% 서식의 패딩

>>> print("%10d" % 12)
        12
>>> print("%-10d" % 12)
12
  • print("%10d" % 12) → 10자리의 공간을 확보하고 우측정렬로 12를 출력하는 명령
  • 기본 정렬이 우측 정렬이므로 좌측에서 아홉 번째 칸부터 12가 출력됨
  • 좌측 정렬을 하기 위해서는 세번째 줄처럼 -부호를 붙이면 됨

실수에서의 자릿수와 소수점 자릿수 지정하기

>>> print ("%10.3f" % 5.94343)        # 10자리를 확보하고 소수점 셋째 자리까지 출력
     5.943
>>> print ("%10.2f" % 5.94343)        # 10자리를 확보하고 소수점 둘째 자리까지 출력
      5.94
>>> print ("%-10.2f" % 5.94343)
5.94
  • ("%10.3f" % 5.94343) → 10자리의 공간을 확보하고 소수점 셋째 자리까지 출력하라는 뜻, 이때 10자리 안에는 소수점이 포함됨
  • 우측 정렬 기준이며 좌측 정렬을 하기 위해서는 -부호를 붙이면 됨

format() 함수의 패딩

>>> print("{0:›10s}".format("Apple"))
     Apple
>>> print("{0:<10s}".format("Apple"))
Apple
  • print("(0:›10s}".format("Apple")) → 10자리의 공간을 확보하고 우측정렬로 문자열 ‘Apple’을 출력하라는 명령
  • 좌측 정렬을 위해서는 ‘{0:<10s}’처럼 <부호를 사용하면 됨

실수에서의 자릿수와 소수점 자릿수 지정

>>> "{1:>10.5f}.".format("Apple", 5.243)
'   5.24300.'
>>> "{1:‹10.5f}.".format("Apple", 5.243)
'5.24300   .'
  • "{1:>10.5f}.".format("Apple", 5.243) → 10자리의 공간을 확보하고, 소수점 다섯 번째 자리까지 실수를 출력, 이때 10자리 안에는 소수점 포함
  • 우측 정렬 기준으로 좌측 정렬을 위해서는 <부호 사용

[참고]

네이밍

  • 변수명을 서식에 할당할 수 있는 네이밍이라는 기능
  • 다음 코드에서 보듯이 기존 번호나 순서대로 자료형에 대응하는 것이 아닌, ‘name'이나 ‘price'처럼 특정 변수명을 사용하여 출력값에 직접 할당 가능
  • 특히 한 번에 출력해야 하는 변수가 많을 때 개발자 입장에서 변수의 순서를 헷갈리지 않고 사용할 수 있다는 장점
>>> print("Product: %(name)5s, Price per unit: %(price)5.5f." % 
{"name":"Apple", "price":5.243})
Product: Apple, Price per unit: 5.24300.
>>> print("Product: {name:>5s}, Price per unit: {price:5.5f}.".format(name="A
pple", price=5.243))
Product: Apple, Price per unit: 5.24300.

실습

단어 카운팅

비틀즈의 노래 <Yesterday>에서 ‘Yesterday’ 라는 단어가 몇 번 나오는지 맞히는 단어 카운팅 프로그램, 해당 가사는 소스파일 폴더에 있는 ‘yesterday.txt’에 저장되어 있음

  • 파일 핸들링 코드를 이용해서 리스트의 형태로 각 줄의 내용 가져오기
# 아직 배우지 않았으므로 그대로 입력하기

f = open("yesterday.txt", 'r')
yesterday_ lyric = f.readlines ()
f.close ()

실행 결과

Number of a Word 'Yesterday' 9
  • 정답
    1. yesterdlay. txt' 파일의 모든 내용을 불러와 yesterday lyric 리스트에 저장한다.
    2. 5~7행에서 for문을 사용하여 yesterday lyric 리스트의 내용을 한 줄씩 불러오면서 contents 변수에 저장한다. 그러면 contents 변수에는 <yesterday> 노래의 모든 가사가 저장된다.
    3. 9~10행에서는 upper() 함수를 사용하여 contents 변수에 있는 모든 값을 대문자로 변환 한 후. count() 함수를 사용하여 대문자 'YESTERDAY'가 몇 개인지를 확인한다. 여기서 contents.upper().count ("YESTERDAY”) 처럼 함수를 붙여써도 된다. upper( ) 함수의 경우 contents 변수에 값 자체를 변경하는 것이 아니라. 변경된 값을 반환해주는 함수이기 때문이다.
    >>> title = "teamlab"
    >>> title
    'teamlab'
    >>> title.upper ()
    'TEAMLAB'
    >>> title
    'teamlab'
    
    • title.upper() 를 실행하면 대문자로 변환되지만 함수 호출 후 title 변수의 내용은 바뀌지 않는다.
    • contents.upper().count ("YESTERDAY") 코드로 특정문자가 있는지 확인 가능
    • 그 결과는 n_of_yesterday 변수에 저장되고 print() 함수로 출력
  • f = open ("yesterday.txt", 'r') yesterday_lyric = f.readlines () f.close () contents = "" for line in yesterday_lyric: contents = contents + line.strip() + "\\n" n_of_yesterday = contents.upper().count ("YESTERDAY") print("Number of a Word 'Yesterday'", n_of_yesterday)

다음 코드의 실행 결과

name = "Hanbit"
a = name.find("H")
b = name.count ("H") * 8
c = len (name) * 2 + 3
print("REMEMBER", str(a) + str(b) + str (c))

정답

REMEMBER 0815
  1. name.find("H") → name에서 H가 몇번째 인덱스에 위치하는지 찾는것이므로 0이 된다.
  2. name.count ("H") * 8 → name 에서 H가 나온 횟수를 카운트하고 8을 곱하여 준다. 이때 H는 1번 나왔으므로 8을 곱하여 8이된다.
  3. len(name) * 2 + 3 → name변수의 길이를 구하고 2를 곱하여 3을 더한다. 이때 name 의 길이 6이므로 결과값은 15가 된다.
  4. print("REMEMBER", str(a) + str(b) + str (c)) 에서 "REMEMBER" 과 str(a) + str(b) + str (c)은 콤마를 기준으로 띄어쓰기 돼서 출력되고 str(a) + str(b) + str (c)은 더하기 연산으로 붙어서 출력되어 0815가 출력된다.