본문 바로가기
Development/Python

파일 읽기

by eoieiie 2023. 8. 19.

파이썬으로 파일 읽기


치킨집의 한 달 매출이 정리되어 있는 파일을 읽어 봅시다.  미리 적혀 있는 파일을 프로젝트와 동일한 경로에 넣어 수정하거나 읽을 수 있고, 프로젝트 안에서 에디터로 작성하여 실행하는 것도 가능하답니다.  먼저 파일의 내용을 살펴보겠습니다.

 

1일: 453400
2일: 388600
3일: 485300
4일: 477900
5일: 432100
6일: 665300
7일: 592500
8일: 465200
9일: 413200
10일: 523000
11일: 488600
12일: 431500
13일: 682300
14일: 633700
15일: 482300
16일: 391400
17일: 512500
18일: 488900
19일: 434500
20일: 645200
21일: 599200
22일: 472400
23일: 469100
24일: 381400
25일: 425800
26일: 512900
27일: 723000
28일: 613600
29일: 416700
30일: 385600
31일: 472300

 

위 파일을 읽으려면 파일이 프로젝트와 동일한 디렉터리에 있다는 가정 하에 아래 코드로 불러올 수 있습니다.

 

with open('chicken.txt','r') as f:
    for line in f:
        print(line)

 

. strip()


그런데 이렇게 읽게 되면 원래의 파일과 동일한 모습으로 출력되지 않습니다. 

치킨집 매출 파일을 하나의 문자열로 생각해 본다면 31개의 줄은 각각 엔터로(ex_ 1일:453400\n) 줄이 나뉘어 있는데, 

print문 역시 항상 엔터를 치기 때문에 위 코드를 사용한다면 결괏값은 다음과 같이 줄 사이사이에 공백을 포함하여 출력됩니다. 

 

1일: 453400

2일: 388600

3일: 485300

4일: 477900

5일: 432100

6일: 665300

.
.
.

31일: 472300

 

이렇게 의도치 않은 공백들을(" " , \n , \t 등등) '화이트스페이스'라고 하며,  strip()으로 이것을 방지할 수 있습니다.  

 

gongbaeck = ("      abc defg\n\n     ")
print((gongbaeck).strip())


#결괏값

abc defg

 

이걸 활용해서 아래와 같이 치킨집 매출 파일을 다시 한번 읽어보면 줄 사이 공백이 없어졌다는 걸 확인할 수 있을 겁니다. 

 

with open('chicken.txt','r') as f:
    for line in f:
        print(line.strip())

 

. split()


. strip()과 함께 데이터 분석에서. split() 역시 유용하게 사용됩니다. 간단하게 설명하자면, 어떤 파라미터를 기준으로 문자열을 나누어 리스트에 저장하는 기능을 가지고 있는 함수입니다. 

간단하게 예시를 들어보겠습니다. 

 

my_string = "1. 2. 3. 4. 5. 6"
my_string.split(". ")


#결괏값

['1','2','3','4','5','6']

 

파라미터인 문자열 ". "을 기준으로 문자열을 나누어 각각 리스트 안에 저장해 준 것을 볼 수 있습니다. 

리스트가 나온 것을 보아하니, 인덱스를 마구 활용할 수 있겠네요.  아래 예시를 한번 살펴보죠.

 

full_name = "hwang, hasom"
name_data = full_name.split(", ")
last_name = name_data[0]
first_name = name_data[1]

print(first_name, last_name)


#결괏값

hasom hwang

 

다만 주의할 점은, 리스트에 저장되는 값들은 모두 문자열로 저장이 되며 연산을 위해서는 int를 씌워주어야 합니다. 

 

numbers = "    \n\n  2  \t  3  \n  5 7 11  \n\n".split()
print(int(numbers[0])+int(numbers[1]))


#결괏값

5

 

코딩에 빠진 닭


위 함수들과 12월 매출이 정리되어 있는 chicken.txt 파일을 활용하여 strip()과 split()을 써서 하루 평균 매출을 출력하는 프로그램을 만들어 봅시다. 평균을 구하기 위해서는 총매출을 총일수로 나누면 됩니다. 현재 파일에는 31일이 있지만, 어떤 달은 31일이 아닐 수  있음을 감안하여 확장성 있는 코드를 짜는 것이 중요합니다. 

다음과 같은 생각을 천천히 하면서 코드를 작성해 보았습니다:

 

1. 파일을 연다. 

 

with open('chicken.txt', 'r') as f:

 

2. 각 줄에서 매출에 해당하는 부분만 int로 묶어서 사용한다. 

 

with open('chicken.txt', 'r') as f:
    total_revenue = 0 
    for line in f:
        data = line.strip().split(": ")
        revenue = int(data[1])
        
        total_revenue += revenue

 

3. 각 줄을 세어 총일수를 계산한다. 

 

with open('chicken.txt', 'r') as f:
    total_revenue = 0 
    total_days = 0 
    
    for line in f:
        data = line.strip().split(": ")
        revenue = int(data[1])
        
        total_revenue += revenue
        total_days += 1

 

4. 총 매출/총일수를 구현한다. 

 

with open('chicken.txt', 'r') as f:
    total_revenue = 0 
    total_days = 0 
    for line in f:
        data = line.strip().split(": ")
        revenue = int(data[1])
        
        total_revenue += revenue
        total_days += 1
                
    print(total_revenue / total_days)

 

이게 정석적인 풀이방식이고, 저는 전체적인 메커니즘은 동일하되, 총 일수를  len() 함수로 구현할 수 있을까?라는 생각을 해 보았습니다. 그런데 여기서는 len()을 포함하여 한 가지 함수를 더 사용할 필요가 있습니다. 왜냐하면 자료형의 길이를 측정하는 len()은 파일 전체를 가져와 시퀀스 자료형으로 만들어야만 제기능을 할 수 있기 때문입니다. 그렇기에 모든 줄을 리스트로 읽어 들여서, 리스트의 길이를 구하는 방식으로 접근해보아야 합니다. 

 

. readlines()


. readlines() 함수는 모든 줄을 읽고 줄을 각각의 리스트에 저장하여, 저장된 자료의 길이에 접근할 수 있게 해 줍니다. 

 

with open('chicken.txt', 'r') as f:
    lines = f.readlines()
    print(lines)
    
    
#결괏값

['1일: 453400\n', '2일: 388600\n', '3일: 485300\n', '4일: 477900\n', '5일: 432100\n', '6일: 665300\n', '7일: 592500\n', '8일: 465200\n', '9일: 413200\n', '10일: 523000\n', '11일: 488600\n', '12일: 431500\n', '13일: 682300\n', '14일: 633700\n', '15일: 482300\n', '16일: 391400\n', '17일: 512500\n', '18일: 488900\n', '19일: 434500\n', '20일: 645200\n', '21일: 599200\n', '22일: 472400\n', '23일: 469100\n', '24일: 381400\n', '25일: 425800\n', '26일: 512900\n', '27일: 723000\n', '28일: 613600\n', '29일: 416700\n', '30일: 385600\n', '31일: 472300']

 

이렇게 되면 굳이. strip()을 사용하지 않아도 공백이 생기지 않고, 문자열이 나열되어 있으므로 len()를 활용할 수 있게 됩니다. 

 

with open('data/chicken.txt', 'r') as f:
    lines = f.readlines()
    
    total_sales = 0
    for line in lines:
        sales = (line.strip().split(': '))[1]
        total_sales += int(sales)
    
    average_sales = total_sales / len(lines)
    print(average_sales)

 

 

이처럼 파일을 읽을 수 있는 방법은 다양합니다. 

 

1. for 문과 함께 사용


with open('chicken.txt','r') as f:
    for line in f:
        print(line)
        
        
#결괏값

1일: 453400

2일: 388600

3일: 485300

.
.
.

31일: 472300

 

2. readlines() 


with open('chicken.txt','r') as f:
    line = f.readlines()
    print(line)
    
    
#결괏값

['1일: 453400\n', '2일: 388600\n', '3일: 485300\n',  ... , '31일: 472300']

 

3. readline()


이 아이는 첫 줄만 읽습니다. 파일의 모든 내용을 읽고 싶다면 while 반복문을 사용하면 됩니다.

 

with open('chicken.txt','r') as f:
    line = f.readline()
    print(line)
    
    
#결괏값

1일: 453400

with open('data/chicken.txt','r') as f:
    line = f.readline()
    while line:
        print(line.strip())
        line = f.readline() #다음 코드를 읽을 준비
    
    
#결괏값

1일: 453400
2일: 388600
3일: 485300

.
.
.

31일: 472300

 

4. read()


줄 바꿈이나 다른 변환 없이 제일 간단하게 프로그램을 불러옵니다.

 

with open('chicken.txt','r') as f:
    file_contents = f.read()
    
    print(file_contents)
    
    
#결괏값

1일: 453400
2일: 388600
3일: 485300

.
.
.

31일: 472300

 

'Development > Python' 카테고리의 다른 글

[파이썬] 딕셔너리 (Dictionary)  (0) 2024.03.09

댓글