본문 바로가기

Programming Language/Python

파이썬_기초단계 알아보기 ep.9 문자부터 파일 수정까지

320x100

서론

 

문자열과 텍스트를 다루는 다양한 방법들을 알아보고,
파일과 데이터를 읽거나 조작하는 형식에 대해서
여러가지를 진행하고자 합니다.

문자열 & 텍스트 & 파일 & 데이터 다루기

문자열 다루기

 

문자열 분리하기

 

문자열을 분리하는 방법은 split() 메서드를 사용합니다.

과연 문자열을 분리해서 도대체 어디에 쓸까 싶지만

추후에 문장으로 되어 있는 리스트를 받았을 때

띄어쓰기를 기준으로 단어를 추출하는

split을 갖고 유용하게 사용할 수 있습니다.

 

구조

 

str.split([sep])

 

예시를 한번 볼까요?

 

coffee_menu_str = "에,스,프,레,소, 아메리카노, 카페라떼, 카푸치노"
coffee_menu_str.split(',')
['에', '스', '프', '레', '소', ' 아메리카노', ' 카페라떼', ' 카푸치노']

 

, 쉼표를 기준으로 문자열이 구분됩니다.

 

split을 문자열에 직접 사용해도 될까요?

 

"에스프레소, 아메리카노, 카페라테, 카푸치노".split(',')
['에스프레소', ' 아메리카노', ' 카페라테', ' 카푸치노']

 

그렇습니다. 직접도 사용할 수 있습니다.

그렇다면 split에 공백을 넣으면 어떻게 될까요?

 

'에스프레소 아메리카노 카페라테 카푸치노'.split(' ')
['에스프레소', '아메리카노', '카페라테', '카푸치노']

 

공백을 기준으로 나눠지게 됩니다. 기본적으로 split()의

디폴트값은 공백입니다.

 

'에스프레소 아메리카노 카페라테 카푸치노'.split()
['에스프레소', '아메리카노', '카페라테', '카푸치노']

 

아무것도 없이도 가능합니다.

 

인자없이 split()을 사용하면 모든 공백과 개행문자를 없앨 수도

있습니다.

 

"  에스프레소 \n\n  아메리카노  \n  카페라테   카푸치노 \n\n" . split()
['에스프레소', '아메리카노', '카페라테', '카푸치노']

 

원하는 횟수만큼만 문자열을 분리할 때에도 사용할 수 있죠

 

구조

 

str.split([sep,] maxsplit=숫자)

 

"에스프레소 아메리카노 카페라테 카푸치노".split(maxsplit=2)
['에스프레소', '아메리카노', '카페라테 카푸치노']

 

뒤의 두 문자열은 분리되지 않았습니다.

 

이를 응용해서 국제번호가 붙어있는 핸드폰 번호를

분리하는 것도 가능합니다.

 

phone_number = "+82-01-2345-6789"
split_num = phone_number.split('-',1)

print(split_num)
print('국내전화번호: {0}'.format(split_num[1]))
['+82', '01-2345-6789']
국내전화번호: 01-2345-6789

 

필요없는 문자열 삭제하기

앞뒤 공백 또는 필요없는 문자를 빠르게

삭제할 수 있는 방법이 있다면?

 

구조

 

str.strip([chars])

 

바로 strip()메서드를 이용하면 가능합니다.

예시를 봐보겠습니다.

 

"aaaaPythonaaaa".strip("a")
'Python'

 

자, 앞뒤의 불필요한 문자들은 날리고, 중간에 있는

문자열만 남길 수 있었습니다.

몇 가지 더 봐볼까요?

 

두 번 실행하기

 

test_str = 'aabbPythonbbbaaaa'
temp1 = test_str.strip('a') # 문자열 앞뒤의 'a' 제거
temp1
'bbPythonbbb'

✂ bb ✂

temp1.strip('b') # 문자열 앞뒤의 'b' 제거
'Python'

 

한꺼번에 지정하기

 

test_str.strip('ab') # 문자열 앞뒤의 'a'와 'b' 제거
'Python'

 

ab, ba 순서는 상관 없습니다.

 

test_str.strip('ba')
'Python'

 

더 많은 문자를 삭제하는 예

 

 

이번에는 문자열 공부를 돕기 위해 프로토스 종족의 다크아칸 군을 데려왔습니다.

 

하이템플러 다크템플러 둘 중 누가더 강하냐는 질문에

이렇게 대답했는데요?

 

'##***!!!##.... DarkTempler...is...powerful.!... %%!#.. '

 

도무지 무슨 말인지 알아들을 수가 없네요.

한번 해석 해볼까요?

 

Dark_archon = '##***!!!##.... DarkTempler...is...powerful.!... %%!#.. '
Dark_archon.strip("#*!>%!@#..")

 

' DarkTempler...is...powerful.!... %%!#.. '

 

무언가 조금 나아진 것 같습니다.

허 근데 정확한 문장은 알아들을 수 없군요🤔

한번 더 번역해볼까요?

 

 

Dark_archon2 = ' DarkTempler...is...powerful.!... %%!#.. '
Dark_archon2.strip('$.* !#..%')
'DarkTempler...is...powerful'

 

아🥳🥳 드디어 알아냈습니다!

들어볼까요

 

'DarkTempler...is...powerful'

 

 

다크템플러가 더 강하다고 하는 것 같습니다.

역시 다크아칸은 같은 편이군요.

 

strip은 공백도 제거할 수 있습니다.

 

'    Python    '.strip(' ')
'Python'

 

지난번에 배운 개행문자도 삭제할 수 있구요.

 

'\n   Python   \n\n'.strip()
'Python'

 

대신 문자열 사이는 없어지지 않습니다.

 

'\n This is very \n fast. \n\n'.strip()
'This is very \n fast.'

 

이번에는 문자열의 왼쪽 혹은 오른쪽만 없애는

strip을 알아보겠습니다.

 

문자열 왼쪽만 lstrip
문자열 오른쪽만 rstrip

 

단순히 left의 l, right의 r만 붙이면 가능합니다.

 

str_lr = "000Python is easy to learn. 000"
print(str_lr.strip('0'))
print(str_lr.strip('0'))
print(str_lr.rstrip('0'))
Python is easy to learn. 
Python is easy to learn. 
000Python is easy to learn.

 

리스트에서 콤마의 공백을 제거 후 공백 제거

 

coffee_menu = '   에스프레소, 아메리카노,  카페라테 ,   카푸치노 '
coffee_menu_list = coffee_menu.split(",")

 

출력

 

coffee_menu_list
['   에스프레소', ' 아메리카노', '  카페라테 ', '   카푸치노 ']

 

응용

 

coffee_list = [] # 빈 리스트 생성
for coffee in coffee_menu_list:
    temp = coffee.strip()  # 문자열의 공백 제거
    coffee_list.append(temp) # 리스트 변수에 공백이 제거된 문자열 추가
    
print(coffee_list) # 최종 문자열 리스트 출력
['에스프레소', '아메리카노', '카페라테', '카푸치노']

 

문자열 연결하기!

더하기 연산자로 문자열을 연결 가능합니다.

 

name1 = "철수"
name2 = "영희"

hello = "님, 주소와 전화번호를 입력해 주세요."
print(name1 + hello)
print(name2 + hello)
철수님, 주소와 전화번호를 입력해 주세요.
영희님, 주소와 전화번호를 입력해 주세요.

 

join() 메서드

문자열을 항목으로 갖는 시퀸스(seq)의 항목 사이에

문자열을 모두 넣은 후 문자열로 반환합니다.

 

구조

 

str.join(seq)


변수를 입력하겠습니다.

 

address_list = ['서울특별시' , '영등포구' , '의사당대로' ,'1']
address_list
['서울특별시', '영등포구', '의사당대로', '1']

 

무작위 주소를 썼는데요.

이곳이 어디인지는

....

 

여러분도 한번 맞춰보셔요!

 

 

이제 join을 써서 따로따로 나눠져 있는 문자열을 합쳐볼까요?

 

a= " "
a.join(address_list)
'서울특별시 영등포구 의사당대로 1'

 

(공백 삭제)

 

' '.join(address_list)
'서울특별시 영등포구 의사당대로 1'

 

바로 국회의사당 이었습니다 🥰

 

join을 이용하면 여러가지 이모티콘을 넣어서도

합칠 수 있습니다.

 

'↖*^-^**↗'.join(address_list)
'서울특별시↖*^-^**↗영등포구↖*^-^**↗의사당대로↖*^-^**↗1'

 

자! 잘 되었습니다.

 

이제 문자열을 검색하는 방법을 보겠습니다.

 

문자열 찾기

문자열 찾기는 다른 프로그램처럼 find() 메서드를 사용할 수 있습니다

 

문자열에서 찾으려는 검색 문자열(search_str)과 첫번째로 

일치하는 문자열(str)의 위치를 반환합니다.

 

구조
str.find(search_str)

 

원하는 로직을 짜거나, 다른 사람이 짠 로직을 복사해서 수정할 때 사용합니다.

 

str_f = "Python code."

print("찾는 문자열의 위치 :", str_f.find("Python"))
print("찾는 문자열의 위치 :", str_f.find("code"))
print("찾는 문자열의 위치 :", str_f.find("n"))
print("찾는 문자열의 위치 :", str_f.find("easy"))
찾는 문자열의 위치 : 0
찾는 문자열의 위치 : 7
찾는 문자열의 위치 : 5
찾는 문자열의 위치 : -1

 

이때, 문자 오류는 '-1'로 표시합니다.

 

시작과 끝 위치는 추가로 지정할 수 있습니다.

 

구조

 

str.find(search_str, start, end)

 

문자 찾기

 

str_f_se = 'THE Python is famous. Python is easy to learn.'

print(str_f_se.find('Python', 0, 10)) # 시작 위치(start)와 끝 위치(end) 지정
print(str_f_se.find('Python', 20)) # 찾기 위한 시작 위치(start) 지정
print(str_f_se.find('Python', 30)) # 오류 출력
4
24
-1

 

이렇게 위치값이 반환됩니다.

해당 문자열이 몇 번 나오는지 알고 싶을때는

count( )  메서드를 사용합니다.

 

구조

 

str.count(search_str)

str.count(search_str, start)

str.count(search_str, start, end)

 

str_c = "Python is powerful. Python is easy to learn. Python is open."

print("Python의 개수는? :", str_c.count("Python"))
print('powerful의 개수는? :', str_c.count('powerful'))
print('IPython의 개수는? :', str_c.count('IPython'))
Python의 개수는? : 3
powerful의 개수는? : 1
IPython의 개수는? : 0

 

좋습니다. 이번엔 문자열이 마지막에 있는지, 처음에 있는지

등을 검사하는 메서드를 알아보겠습니다.

 

startwith( )과 endswith ( )

 

해당 문자열로 시작하는지, 끝나는지 검사합니다.

시작하거나 끝나면 True, 아니면 False를 출력합니다.

 

str_se = "Python is powerful. Python is easy to learn."

print('Python으로 시작? :', str_se.startswith("Python"))
print('is로 시작? :', str_se.startswith('is'))
print('.로 끝? :', str_se.endswith('.'))
print('learn으로 끝? :', str_se.endswith('learn'))
Python으로 시작? : True
is로 시작? : False
.로 끝? : True
learn으로 끝? : False

 

python, is, . , learn의 문자열이 있는지 찾아서

반환했습니다😚

검사도 했으니, 문자열을 교체하는 방법도 알아보겠습니다.

 

문자열 바꾸기

replace( ) 를 사용하면 지정한 문자열을 찾아서

특정한 문자열로 바꿀 수 있습니다.

 

메서드 구조

 

str.replace(old, new, maxcount)

 

str_a = 'Python is fast. Python is friendly. Python is open.'
print(str_a.replace('Python','IPython'))
print(str_a.replace('Python','IPython',0))
print(str_a.replace('Python','IPython',-1))
print(str_a.replace('Python','IPython',2))
IPython is fast. IPython is friendly. IPython is open.
Python is fast. Python is friendly. Python is open.
IPython is fast. IPython is friendly. IPython is open.
IPython is fast. IPython is friendly. Python is open.

 

모두 위치를 지정하고 바뀌는 것을 알 수 있습니다.

반대로 문자를 제거할 때도 사용합니다.

 

str_b = '[Python] [is] [fast]'
str_b1 = str_b.replace('[','')
str_b2 = str_b.replace(']','')

 

출력

 

print(str_b1)
print(str_b2)
print(str_b)
Python] is] fast]
[Python [is [fast
[Python] [is] [fast]

 

다음은 문자열이 어떻게 구성되어 있는지 검사하고

이를 활용하기 위해 사용하는 메서드 입니다.

숫자, 문자, 공백 등 다양한 문자형을 검사하고

 참/거짓을 분별합니다.

 

문자열 구성 확인하기

 

종류

 

isalpha() = 문자열이 숫자, 특수문자, 공백이 아닌 문자로 구성되어 있을 때만 True

isdigit() = 문자열이 모두 숫자로 구성되어 있을 때만 True

isalnum() = 문자열이 특수 문자나 공백이 아닌 문자와 숫자로 구성되어 있을때만 True

isspace() = 문자열이 모두 공백 문자로 구성되어 있을때만 True

isupper() = 문자열이 모두 로마자 대문자로 구성되어 있을때만 True

islower() = 문자열이 모두 로마자 소문자로 구성되어 있을때만 True

 

문자로만 구성되어 있는지 검사합니다 (alpha는 alphabet)

 

print("Python". isalpha()) # 문자열에 공백, 특수 문자, 숫자가 없음
print("Ver. 3.x".isalpha()) # 공백, 특수 문자, 숫자 중 하나가 있음
True
False

 

숫자로만 구성되어 있는지 검사합니다 (digit는 아라비아 숫자)

 

print("12345".isdigit()) # 문자열이 모두 숫자로 구성됨
print("12345abc".isdigit()) # 문자열이 숫자로만 구성되지 않음
True
False

 

문자 혹은 숫자만 있는지 검사합니다. (alphabet + num)

 

print('abc12345'.isalnum()) # 특수 문자나 공백이 아닌 문자와 숫자로 구성됨
print('    abc12345'.isalnum()) # 문자열에 공백이 있음
True
False

 

공백만 있는지 검사합니다. (space : 공백)

 

print('    '.isspace()) # 문자열이 공백으로만 구성됨
print('   1  '.isspace()) # 문자열에 공백 외에 다른 문자가 있음
True
False

 

대문자(upper) 혹은 소문자(lower)만 있는지 검사합니다.

 

print('PYTHON'.isupper())
print('Python'.isupper())
print('python'.islower())
print('Python'.islower())
True
False
True
False

 

응용해서 문자를 대문자/ 소문자로 변경하는 것도

가능합니다.

 

대소문자로 변경하기

파이썬에서 대문자로 쓰여 있는 문자열은 

소문자로 쓰여 있는 문자열과 절대 일치할 수 없습니다.

대문자로 시작하는지, 소문자로 시작하는지 구분은

확실하게 차이가 납니다.

 

'Python' == 'python'
'Python' == 'python'

 

구조

 

str.upper = 모두 대문자로 변경

str.lower = 모두 소문자로 변경

 

대문자로 변경하고, 바로 소문자로 변경합니다.

 

string1 = 'Python is powerful. PYTHON IS EASY TO LEARN.'
print(string1.upper())
print(string1.lower())
PYTHON IS POWERFUL. PYTHON IS EASY TO LEARN.
python is powerful. python is easy to learn.

 

lower와 upper을 이용해서 문자열을 비교해볼까요?

 

print('Python'.lower() == 'python'.lower())
print('Python'.upper() == 'python'.upper())
True
True

 

잘 되었습니다.

 

텍스트 파일의 데이터를 읽고 처리하기

 

2022년 대한민국은 바야흐로 커피 공화국 입니다.

커피콩도 자라지 않는데 어떻게 커피 공화국 이냐구요?☕

 

커피의 주산지나, 1차 수입하는 곳도 아니지만

대한민국은 100m 에 하나씩은 카페가 보이는 

친절한 국가가 되었습니다. 유명한 관광지는 이 현상이

더욱 심하죠? 몇몇 제주도 관광지는 10m에 하나씩

개인 카페가 있는 것을 볼 수 있습니다🍵

 

여러분도 이 기세에 힘입어, 모두 함께

작은 카페를 하나 창업했다고 생각해봅시다.

 

개업한 이번주 4일간의 각 커피별 판매량을 정리할 수 있을까요?

 

 

데이터 파일 준비

 

아래는 파일은 필자의 C드라이브에 카페 판매량을 저장할 경로를

지정하는 코드입니다.

 

cd C:\myPyCode\data\

 

그리고 12월 2일부터 5일까지 4일간, 에스프레소, 아메리카노,

카페라테, 카푸치노, 아이스바닐라라떼까지 총 5가지 커피를 

판매했는데요. 

 

아직까지는 정리된 게 보이지 않습니다.

파이썬에도 입력해볼까요?

 

f = open('coffeeShopSales.txt','w')
f.write(' 날짜    에스프레소  아메리카노  카페라테  카푸치노   아이스바닐라라떼 \n')
f.write('12.2        10          50         45        20              10 \n')
f.write('12.3        12          45         41        18              20 \n')
f.write('12.4        11          90         42        19              30 \n')
f.write('12.5        10          80         30        21              40 \n')
f.close()

 

이제 저장한 파일을 다시 열어보겠습니다.

!type을 사용합니다.

 

!type C:\myPyCode\data\coffeeShopSales.txt
 날짜    에스프레소  아메리카노  카페라테  카푸치노   아이스바닐라라떼 
12.2        10          50         45        20              10 
12.3        12          45         41        18              20 
12.4        11          90         42        19              30 
12.5        10          80         30        21              40

 

좋습니다. 실제로 들어간 경로에 보면, 파일도 만들어진 것을

볼 수 있습니다.

 

 

이제 이 파일명을 변수로 지정하고, 

한 줄씩 읽기 + 한줄씩 출력을 진행합니다.

 

file_name = 'C:\myPyCode\data\coffeeShopSales.txt'

f = open(file_name)        # 파일 열기
for line in f:            # 한 줄씩 읽기
    print(line, end='')   # 한 줄씩 출력
f.close()                 # 파일 닫기
 날짜    에스프레소  아메리카노  카페라테  카푸치노   아이스바닐라라떼 
12.2        10          50         45        20              10 
12.3        12          45         41        18              20 
12.4        11          90         42        19              30 
12.5        10          80         30        21              40

 

네. 이제 일종의 column과 행 입력 내용들을 분리해보겠습니다.

 

파일에서 읽은 문자열 데이터 처리

첫번째 줄에 있는 항목 이름을 가져와 빈칸을 기준으로 나누고

두번째 줄 이후의 항목값을 처리합니다.

 

f = open(file_name)    # 파일 열기
header = f.readline()  # 데이터의 첫 번째 줄을 읽음
f.close()              # 파일 닫기

header

 

' 날짜    에스프레소  아메리카노  카페라테  카푸치노   아이스바닐라라떼 \n'

 

날짜와 각 커피명들이 나눠졌죠? 이번에는

split( )을 이용해 리스트를 만들겠습니다.

 

header_list = header.split()  # 첫 줄의 문자열을 분리 후 리스트로 변환
header_list
['날짜', '에스프레소', '아메리카노', '카페라테', '카푸치노', '아이스바닐라라떼']

 

column도 만들었으니 이제 날짜값과 판매값들을

데이터로 넣어보겠습니다.

 

for문을 사용합니다.

 

f = open(file_name)
header= f.readline()
header_list = header.split()

for line in f:
    data_list = line.split()
    print(data_list)
    
f.close()
['12.2', '10', '50', '45', '20', '10']
['12.3', '12', '45', '41', '18', '20']
['12.4', '11', '90', '42', '19', '30']
['12.5', '10', '80', '30', '21', '40']

 

거의 다 왔습니다.

이제 문자열로 되어 있는 리스트를 숫자로 변환하고

커피의 종류별로 판매량 데이터를 분류해서

넣어보겠습니다.

 

물론 변수는 영어로 설정하지 않고, 다른 문자로 바꿔도

얼마든지 무방합니다. (길어졌네요)

 

f = open(file_name)            # 데이터의 첫번째 줄을 읽음
header = f.readline()          # 첫 줄의 문자열을 분리한 후 리스트로 전환
headerList = header.split()   

espresso = []                  # 커피 종류별로 빈 리스트 생성
americano = []
cafelatte = []
cappucino = []
icevanillalatte = []

for line in f:                 # 두 번째 줄부터 데이터를 읽어서 반복적으로 처리
    dataList = line.split()    # 문자열에서 공백을 제거해서 문자열 리스트로 변환
    
    #커피 종류별로 정수로 변환한 후, 리스트 항목으로 추가
    espresso.append(int(dataList[1]))
    americano.append(int(dataList[2]))
    cafelatte.append(int(dataList[3]))
    cappucino.append(int(dataList[4]))
    icevanillalatte.append(int(dataList[5]))
    
f.close()  # 파일 닫기

print("{0} : {1} ".format(headerList[1], espresso))     # 각 변수에 할당된 값을 출력합니다.
print("{0} : {1} ".format(headerList[2], americano))
print("{0} : {1} ".format(headerList[3], cafelatte))
print("{0} : {1} ".format(headerList[4], cappucino))
print("{0} : {1} ".format(headerList[5], icevanillalatte))
에스프레소 : [10, 12, 11, 10] 
아메리카노 : [50, 45, 90, 80] 
카페라테 : [45, 41, 42, 30] 
카푸치노 : [20, 18, 19, 21] 
아이스바닐라라떼 : [10, 20, 30, 40]

 

자 이제, 4일간의 메뉴별 판매량과 하루 평균 판매한 잔을

출력해볼까요?

지금까지 배웠던 함수들을 총집합 합니다.

 

total_sum = [sum(espresso), sum(americano), sum(cafelatte), sum(cappucino), sum(icevanillalatte)]
total_average = [sum(espresso)/len(espresso), sum(americano)/len(americano), sum(cafelatte)/len(cafelatte), sum(cappucino)/len(cappucino), sum(icevanillalatte)/len(icevanillalatte)]

for k in range(len(total_sum)):
    print('[{0}] 판매량'.format(headerList[k+1]))
    print('- 4일 전체 : {0}, 하루 평균 : {1}'.format(total_sum[k], total_average[k]))
[에스프레소] 판매량
- 4일 전체 : 43, 하루 평균 : 10.75
[아메리카노] 판매량
- 4일 전체 : 265, 하루 평균 : 66.25
[카페라테] 판매량
- 4일 전체 : 158, 하루 평균 : 39.5
[카푸치노] 판매량
- 4일 전체 : 78, 하루 평균 : 19.5
[아이스바닐라라떼] 판매량
- 4일 전체 : 100, 하루 평균 : 25.0

 

자 모두 도출되었습니다!

에스프레소가 가장 적게, 아메리카노가 가장 많이 판매되었네요.

역시 한국인의 아메리카노 사랑은 끝이 없습니다!🤗

 

 

이렇게해서, 문자열과 텍스트, 파일, 데이터를 모두 다뤄보았습니다.

 

파이썬의 기초단계는 모두 종료되었고, 다음 게시물부터는

딥러닝과 데이터 분석을 위한 파이썬의 새로운 라이브러리 Numpy

를 간단하게 소개하는 시간을 갖고자 합니다.

 

고생 많으셨습니다.

 

 

-파이썬_기초단계 끝-

 

728x90