파일을 한 줄씩 목록으로 읽는 방법은 무엇입니까?


2027

파이썬에서 파일의 모든 줄을 읽고 각 줄을 목록의 요소로 저장하려면 어떻게합니까?

파일을 한 줄씩 읽고 각 줄을 목록 끝에 추가하고 싶습니다.

답변:


2174
with open(filename) as f:
    content = f.readlines()
# you may also want to remove whitespace characters like `\n` at the end of each line
content = [x.strip() for x in content] 

206
-loop file.readlines()에서 사용하지 마십시오 for. 파일 객체 자체는 충분합니다.lines = [line.rstrip('\n') for line in file]
jfs

88
BigData를 사용하는 경우 MemoryErrorreadlines() 가 발생할 수 있으므로 효율적이지 않습니다 . 이 경우 각 변수를 사용 하고 작업 하는 파일을 반복하는 것이 좋습니다 . for line in f:line
DarkCygnus

7
여기에 언급 된 절차를 사용하여 답변에 주어진 다양한 방법으로 메모리 프로파일을 확인했습니다 . @DevShark here에서 제안한 것처럼 파일에서 각 줄을 읽고 처리 할 때 메모리 사용량이 훨씬 더 좋습니다 . 메모리가 제한적이거나 파일이 큰 경우 컬렉션 객체에 모든 줄을 유지 하는 것은 좋은 생각 이 아닙니다 . 실행 시간은 두 방법 모두 비슷합니다.
Tirtha R

6
또한 .rstrip()줄 끝에서 공백을 제거하면 약간 더 빠르게 작동합니다.
Gringo Suave 2016 년

Oneliner :with open(filename) as f: content = [i.strip() for i in f.readlines()]
Vishal Gupta

1002

입력 및 출력 참조 :

with open('filename') as f:
    lines = f.readlines()

또는 개행 문자를 제거하여 :

with open('filename') as f:
    lines = [line.rstrip() for line in f]

12
더 나은 방법 f.read().splitlines()은 개행을 제거합니다
Mark

for line in open(filename)안전한 두 번째 버전 입니까? 즉, 파일이 자동으로 닫히나요?
becko

2
전체 파일을 한 번에 메모리로 읽는 대신 한 번에 한 줄씩 파일을 읽는 것이 가장 좋습니다. 그렇게하면 큰 입력 파일로 확장 할 수 없습니다. 아래의 robert 답변을 참조하십시오.
Brad Hein

1
lines = [x.rstrip('\n') for x in open('data\hsf.txt','r')]이 방법으로 쓴 경우 읽은 후 파일을 닫을 수 있습니까?
Ramisa Anjum Aditi

2
그렇습니다. 다른 사람들이 여기에서하고있는 시점 open까지 컨텍스트 관리자없이 사용하는 것이 "모범 사례"가 아니 거나 다른 확실한 방법은 아닙니다. 그러나 객체가 더 이상 참조가없는 경우는 실제로 그러한 경우 중 하나가 아닙니다. 그것으로 가비지 수집되고 파일이 닫힙니다. 목록 이해가 처리되면 오류가 발생하거나 즉시 발생해야합니다.
Aaron Hall

579

이것은 필요 이상으로 명시 적이지만 원하는 것을 수행합니다.

with open("file.txt") as file_in:
    lines = []
    for line in file_in:
        lines.append(line)

18
전체 파일을 메모리에로드 할 필요가 없기 때문에이 대답을 선호합니다 (이 경우 여전히 추가 array되지만 다른 상황이있을 수 있음). 큰 파일의 경우이 방법으로 문제를 완화 할 수 있습니다.
JohannesB

1
배열에 추가하는 것이 느립니다. 이것이 최선의 해결책 인 유스 케이스를 생각할 수 없습니다.
Elias Strehle

@haccks는 전체 파일을 메모리에로드하지 않거나 더 많기 때문에 더 낫습니까?
OrigamiEye

4
참고 : 이 솔루션은 줄 바꾸기를 제거하지 않습니다.
AMC

1
이 솔루션은 전체 파일을 메모리에로드합니다. 사람들이 왜 그렇게 생각하지 않는지 모르겠습니다.
andrebrait

274

이렇게하면 파일에서 "배열"라인이 생성됩니다.

lines = tuple(open(filename, 'r'))

open반복 할 수있는 파일을 반환합니다. 파일을 반복 할 때 해당 파일에서 줄을 가져옵니다. tuple주어진 반복자에서 반복자를 가져 와서 튜플 인스턴스를 인스턴스화 할 수 있습니다. lines파일 라인에서 작성된 튜플입니다.


31
@MarshallFarrier lines = open(filename).read().split('\n')대신 시도하십시오 .
녹 티스 스카이 타워

16
파일을 닫습니까?
Vanuan

5
@Vanuan 줄이 실행 된 후에 파일에 대한 참조가 남아 있지 않으므로 소멸자 파일을 자동으로 닫아야합니다.
녹 티스 스카이 타워

30
@NoctisSkytower lines = open(filename).read().splitlines()좀 더 깨끗하고 DOS 줄 끝을 더 잘 처리한다고 생각합니다.
jaynp

8
@ mklement0 1000 줄의 파일을 가정하면 a list가 a보다 13.22 % 더 많은 공간을 차지합니다 tuple. 결과는에서 나옵니다 from sys import getsizeof as g; i = [None] * 1000; round((g(list(i)) / g(tuple(i)) - 1) * 100, 2). 를 tuple만들 때보 다 0.117 % 더 많은 시간이 걸립니다 list(0.16 % 표준 편차). 결과는 from timeit import timeit as t; round((t('tuple(i)', 'i = [None] * 1000') / t('list(i)', 'i = [None] * 1000') - 1) * 100, 2)30 회 실행 됩니다. 내 솔루션은 변경 필요성이 알려지지 않은 경우 속도보다 공간을 선호합니다.
녹 티스 스카이 타워

194

\n포함 하고 싶은 경우 :

with open(fname) as f:
    content = f.readlines()

\n포함 하지 않으려 는 경우 :

with open(fname) as f:
    content = f.read().splitlines()

168

Python의 Files of File Objects 에 따르면 텍스트 파일을 a로 변환하는 가장 간단한 방법 list은 다음과 같습니다.

with open('file.txt') as f:
    my_list = list(f)

텍스트 파일 행을 반복해야하는 경우 다음을 사용할 수 있습니다.

with open('file.txt') as f:
    for line in f:
       ...

오래된 답변 :

사용 with하여 readlines():

with open('file.txt') as f:
    lines = f.readlines()

파일 닫기에 신경 쓰지 않으면이 단일 라이너가 작동합니다.

lines = open('file.txt').readlines()

전통적인 방법 :

f = open('file.txt') # Open file on read mode
lines = f.read().split("\n") # Create a list containing all lines
f.close() # Close file

150

제안 된대로 간단하게 다음을 수행 할 수 있습니다.

with open('/your/path/file') as f:
    my_lines = f.readlines()

이 방법에는 두 가지 단점이 있습니다.

1) 모든 라인을 메모리에 저장합니다. 일반적으로 이것은 매우 나쁜 생각입니다. 파일이 매우 커서 메모리가 부족할 수 있습니다. 크지 않더라도 단순히 메모리 낭비입니다.

2) 각 줄을 읽을 때 처리 할 수 ​​없습니다. 따라서이 후에 행을 처리하면 효율적이지 않습니다 (하나가 아닌 두 개의 패스가 필요함).

일반적인 경우에 대한 더 나은 접근 방식은 다음과 같습니다.

with open('/your/path/file') as f:
    for line in f:
        process(line)

프로세스 기능을 원하는 방식으로 정의 할 수 있습니다. 예를 들면 다음과 같습니다.

def process(line):
    if 'save the world' in line.lower():
         superman.save_the_world()

( Superman클래스 구현은 연습으로 남겨 두어야합니다).

이것은 모든 파일 크기에 잘 작동하며 1 패스로 파일을 통과합니다. 이것은 일반적으로 일반 파서가 작동하는 방식입니다.


5
이것은 내가 필요한 것입니다-단점을 설명해 주셔서 감사합니다. 파이썬 초보자는 왜 솔루션이 솔루션인지 이해하는 것이 좋습니다. 건배!
Ephexx

5
조금 더 코리를 생각하십시오. 이 줄에 아무 것도하지 않고 컴퓨터가 각 줄을 읽도록 하시겠습니까? 분명히 당신은 항상 어떤 방법 으로든 처리해야한다는 것을 알 수 있습니다.
DevShark

5
항상 라인으로 무언가를해야합니다. 행을 인쇄하거나 계산하는 것만 큼 간단 할 수 있습니다. 프로세스가 메모리에서 행을 읽도록하더라도 아무런 가치가 없습니다.
DevShark

2
당신은 항상 그들과 무언가를해야합니다. 나는 당신이 만들고자하는 요점은 기능을 하나씩이 아니라 한 번에 모두 적용 할 수 있다는 것입니다. 실제로는 때때로 그런 경우입니다. 그러나 메모리 관점에서는 매우 비효율적이며 풋 프린트가 Ram보다 큰 경우 파일을 읽을 수 없습니다. 그렇기 때문에 일반적으로 일반 파서는 내가 설명한 방식으로 작동합니다.
DevShark

2
@PierreOcinom 맞습니다. 파일이 읽기 전용 모드로 열린 경우 위의 코드로 원본 파일을 수정할 수 없습니다. 읽고 쓸 수있는 파일을 열려면 다음을 사용하십시오.open('file_path', 'r+')
DevShark

63

목록으로 데이터

다음 줄과 같이 데이터가 포함 된 텍스트 파일이 있다고 가정합니다.

텍스트 파일 내용 :

line 1
line 2
line 3
  • 동일한 디렉토리에서 cmd를여십시오 (마우스를 마우스 오른쪽 단추로 클릭하고 cmd 또는 PowerShell을 선택하십시오)
  • 실행 python하고 인터프리터에서 다음을 작성하십시오.

파이썬 스크립트 :

>>> with open("myfile.txt", encoding="utf-8") as file:
...     x = [l.strip() for l in file]
>>> x
['line 1','line 2','line 3']

추가 사용 :

x = []
with open("myfile.txt") as file:
    for l in file:
        x.append(l.strip())

또는:

>>> x = open("myfile.txt").read().splitlines()
>>> x
['line 1', 'line 2', 'line 3']

또는:

>>> x = open("myfile.txt").readlines()
>>> x
['linea 1\n', 'line 2\n', 'line 3\n']

또는:

def print_output(lines_in_textfile):
    print("lines_in_textfile =", lines_in_textfile)

y = [x.rstrip() for x in open("001.txt")]
print_output(y)

with open('001.txt', 'r', encoding='utf-8') as file:
    file = file.read().splitlines()
    print_output(file)

with open('001.txt', 'r', encoding='utf-8') as file:
    file = [x.strip() for x in file.readlines()]
    print_output(file)

산출:

lines_in_textfile = ['line 1', 'line 2', 'line 3']
lines_in_textfile = ['line 1', 'line 2', 'line 3']
lines_in_textfile = ['line 1', 'line 2', 'line 3']

입니다 encoding="utf-8"필요?
Mausy5043

@ Mausy5043 아니오, 그러나 텍스트 파일을 읽을 때 이상한 문자가있을 수 있습니다 (특히 이탈리아어로)
Giovanni G. PY

1
read().splitlines()파이썬이 당신에게 제공합니다 : 그것은 간단합니다 readlines()(아마 낭비가 적기 때문에 더 빠를 것입니다).
Eric O Lebigot

도시 된 실시 예에서 @EricOLebigot, 그 모양 read().splitlines()readlines()같은 출력을 생성하지 않는다. 그것들이 동등하다고 확신합니까?
craq

readlines 만 사용하는 경우 텍스트에서 \ n을 제거하기 위해 strip 메소드를 사용해야하므로 두 경우 모두 목록 이해를 사용하여 마지막 예제를 변경하여 동일한 출력을 갖습니다. 따라서 read (). readlines ()를 사용하면 줄이 있고 줄 바꿈 문자가없는 "깨끗한"항목이 있습니다. 그렇지 않으면 위의 코드에 표시된대로해야합니다.
Giovanni G. PY

43

파일을 목록으로 읽으려면 다음 세 가지를 수행해야합니다.

  • 파일을여십시오
  • 파일을 읽으십시오
  • 내용을 목록으로 저장

다행스럽게도 파이썬은 이러한 작업을 매우 쉽게하기 때문에 파일을 목록으로 읽는 가장 짧은 방법은

lst = list(open(filename))

그러나 나는 더 많은 설명을 추가 할 것입니다.

파일 열기

특정 파일을 열고 파일 핸들 (또는 파일과 같은 핸들)을 직접 처리하지 않는다고 가정합니다. Python에서 파일을 여는 데 가장 일반적으로 사용되는 함수는 open입니다. Python 2.7에서는 하나의 필수 인수와 두 개의 선택적 인수가 필요합니다.

  • 파일 이름
  • 방법
  • 버퍼링 (이 답변에서는이 인수를 무시합니다)

파일 이름은 파일 경로를 나타내는 문자열이어야 합니다 . 예를 들면 다음과 같습니다.

open('afile')   # opens the file named afile in the current working directory
open('adir/afile')            # relative path (relative to the current working directory)
open('C:/users/aname/afile')  # absolute path (windows)
open('/usr/local/afile')      # absolute path (linux)

파일 확장자를 지정해야합니다. 탐색기에서 볼 때 .txt또는 .doc등의 파일 확장자 는 기본적으로 숨겨져 있기 때문에 Windows 사용자에게 특히 중요합니다 .

두 번째 인수는이다 mode그것을이다,r 수단 "읽기 전용"기본적으로. 그것이 바로 귀하의 경우에 필요한 것입니다.

그러나 실제로 파일을 만들거나 파일에 쓰려면 여기에서 다른 인수가 필요합니다. 당신이 개요를 원한다면 훌륭한 답변이 있습니다 .

파일을 읽기 위해 파일을 생략 mode하거나 명시 적으로 전달할 수 있습니다 .

open(filename)
open(filename, 'r')

둘 다 파일을 읽기 전용 모드로 엽니 다. Windows에서 바이너리 파일을 읽으려면 모드를 사용해야합니다 rb.

open(filename, 'rb')

다른 플랫폼에서는 'b'이진 모드가 무시됩니다.


이제 open파일 사용법을 보여 주었으므로, 항상 필요한 사실에 대해 이야기 해 봅시다close 다시 . 그렇지 않으면 프로세스가 종료 될 때까지 파일에 열린 파일 핸들을 유지합니다 (또는 Python이 파일 핸들을 가비지시킵니다).

사용할 수있는 동안 :

f = open(filename)
# ... do stuff with f
f.close()

그 사이에 뭔가 때 파일을 닫 실패 open하고 close예외가 발생합니다. a tryfinally: 를 사용하여이를 피할 수 있습니다 .

f = open(filename)
# nothing in between!
try:
    # do stuff with f
finally:
    f.close()

그러나 파이썬은 예뻐 구문이 컨텍스트 관리자를 제공합니다 (그러나 대한 open그것은 거의 동일입니다 tryfinally이상) :

with open(filename) as f:
    # do stuff with f
# The file is always closed after the with-scope ends.

마지막 접근 방식은 파이썬에서 파일을 여는 데 권장되는 접근 방식입니다 !

파일 읽기

이제 파일을 열었습니다. 이제 파일을 읽는 방법은 무엇입니까?

open함수는 file객체를 반환하고 Pythons 반복 프로토콜을 지원합니다. 각 반복은 당신에게 줄을 줄 것입니다 :

with open(filename) as f:
    for line in f:
        print(line)

파일의 각 줄이 인쇄됩니다. 그러나 각 줄에는 \n끝에 줄 바꿈 문자가 포함됩니다 (파이썬이 범용 줄 바꿈 지원으로 빌드되어 있는지 확인하고 싶을 수도 있습니다. 그렇지 않으면 \r\nWindows 또는 \rMac에서 줄 바꿈으로 사용할 수도 있음). 원하지 않는 경우 마지막 문자 (또는 Windows의 마지막 두 문자)를 간단히 제거 할 수 있습니다.

with open(filename) as f:
    for line in f:
        print(line[:-1])

그러나 마지막 줄에는 반드시 줄 바꿈 문자가 없어야하므로 그것을 사용해서는 안됩니다. 후행 줄 바꿈으로 끝나는 지 확인하고 제거하면 제거 할 수 있습니다.

with open(filename) as f:
    for line in f:
        if line.endswith('\n'):
            line = line[:-1]
        print(line)

하지만 당신은 간단합니다 (을 포함한 모든 공백 제거 할 수 \n로부터 문자) 문자열의 끝 이 또한 다른 모든 제거 뒤에 당신이이 중요한 경우주의해야하므로 공백을 :

with open(filename) as f:
    for line in f:
        print(f.rstrip())

그러나 줄이 \r\n(Windows "newlines")로 끝나는 경우 .rstrip()에도\r !

내용을 목록으로 저장

이제 파일을 열고 읽는 방법을 알았으므로 내용을 목록에 저장해야합니다. 가장 간단한 옵션은 list함수 를 사용하는 것입니다.

with open(filename) as f:
    lst = list(f)

후행 줄 바꿈을 제거하려면 대신 목록 이해를 사용할 수 있습니다.

with open(filename) as f:
    lst = [line.rstrip() for line in f]

또는 더 간단합니다 : 기본적으로 객체 의 .readlines()메소드 는 행 중 file하나 list를 반환합니다 .

with open(filename) as f:
    lst = f.readlines()

여기에는 후행 줄 바꿈 문자도 포함됩니다. 원하지 않는 경우 [line.rstrip() for line in f]메모리에 모든 줄을 포함하는 두 목록을 유지하지 않기 때문에 접근 방식을 권장합니다 .

원하는 출력을 얻을 수있는 추가 옵션이 있지만 read, 문자열에 완전한 파일을 넣은 다음 줄 바꿈으로 분할하는 것이 "최적"입니다 .

with open(filename) as f:
    lst = f.read().split('\n')

또는:

with open(filename) as f:
    lst = f.read().splitlines()

split캐릭터가 포함되지 않기 때문에 후행 줄 바꿈을 자동으로 처리합니다 . 그러나 파일을 문자열과 메모리의 행 목록으로 유지하기 때문에 이상적이지 않습니다!

요약

  • with open(...) as f파일을 직접 닫을 필요가없고 일부 예외가 발생하더라도 파일을 닫을 수 있으므로 파일을 열 때 사용하십시오 .
  • file 객체는 반복 프로토콜을 지원하므로 파일을 한 줄씩 읽는 것이 간단합니다. for line in the_file_object: .
  • 사용 가능한 기능 / 클래스에 대한 설명서를 항상 찾아보십시오. 대부분의 경우 작업 또는 하나 이상의 좋은 작업과 완벽하게 일치합니다. 이 경우 확실한 선택 readlines()이지만 목록에 저장하기 전에 행을 처리하려면 간단한 목록 이해를 권장합니다.

마지막 접근 방식은 파이썬에서 파일을 여는 데 권장되는 접근 방식입니다! 그렇다면 왜 마지막일까요? 계속 진행하기 전에 대다수의 사람들이 대답의 처음 몇 줄을 보지 않습니까?
AMC

@ AMC 나는 대답을 쓸 때 그것에 대해 많이 생각하지 않았습니다. 답의 맨 위에 놓아야한다고 생각하십니까?
MSeifert

가장 좋을 수도 있습니다 또한 방금 파이썬 2에 대해 언급 했으므로 업데이트 될 수도 있습니다.
AMC

아 문제는 원래 python-2.x로 태그되었습니다. 보다 일반적으로 업데이트하는 것이 좋습니다. 다음에 내가 올지 봅시다. 제안 해 주셔서 감사합니다. 매우 감사!
MSeifert

42

파일의 행을 목록으로 읽는 깨끗하고 파이썬적인 방법


무엇보다도 파일을 열고 효율적이고 파이썬적인 방식으로 내용을 읽는 데 중점을 두어야합니다. 개인적으로 선호하지 않는 방법의 예는 다음과 같습니다.

infile = open('my_file.txt', 'r')  # Open the file for reading.

data = infile.read()  # Read the contents of the file.

infile.close()  # Close the file since we're done using it.

대신, 매우 깨끗하기 때문에 읽기 및 쓰기를 위해 파일을 여는 아래 방법을 선호하며 파일 사용이 끝나면 파일을 닫는 추가 단계가 필요하지 않습니다. 아래 문장에서 읽을 파일을 열고 변수 'infile'에 할당합니다. 이 명령문 내의 코드 실행이 완료되면 파일이 자동으로 닫힙니다.

# Open the file for reading.
with open('my_file.txt', 'r') as infile:

    data = infile.read()  # Read the contents of the file into memory.

이제이 데이터를 반복 가능하고 효율적이며 유연하기 때문에이 데이터를 Python List 로 가져 오는 데 집중해야합니다 . 귀하의 경우 원하는 목표는 텍스트 파일의 각 줄을 별도의 요소로 가져 오는 것입니다. 이를 위해 splitlines () 메소드를 다음과 같이 사용합니다.

# Return a list of the lines, breaking at line boundaries.
my_list = data.splitlines()

최종 제품 :

# Open the file for reading.
with open('my_file.txt', 'r') as infile:

    data = infile.read()  # Read the contents of the file into memory.

# Return a list of the lines, breaking at line boundaries.
my_list = data.splitlines()

우리의 코드 테스트 :

  • 텍스트 파일의 내용 :
     A fost odatã ca-n povesti,
     A fost ca niciodatã,
     Din rude mãri împãrãtesti,
     O prea frumoasã fatã.
  • 테스트 목적을위한 인쇄 문 :
    print my_list  # Print the list.

    # Print each line in the list.
    for line in my_list:
        print line

    # Print the fourth element in this list.
    print my_list[3]
  • 출력 (유니 코드 문자로 인해 다른 모양) :
     ['A fost odat\xc3\xa3 ca-n povesti,', 'A fost ca niciodat\xc3\xa3,',
     'Din rude m\xc3\xa3ri \xc3\xaemp\xc3\xa3r\xc3\xa3testi,', 'O prea
     frumoas\xc3\xa3 fat\xc3\xa3.']

     A fost odatã ca-n povesti, A fost ca niciodatã, Din rude mãri
     împãrãtesti, O prea frumoasã fatã.

     O prea frumoasã fatã.

30

Python 3.4에서 도입되었으며 pathlib다음과 같이 파일에서 텍스트를 읽는 편리한 방법이 있습니다.

from pathlib import Path
p = Path('my_text_file')
lines = p.read_text().splitlines()

( splitlines호출은 파일의 전체 내용을 포함하는 문자열에서 파일의 행 목록으로 변환하는 것입니다).

pathlib편리한 기능이 많이 있습니다. read_text훌륭하고 간결하며 파일을 열고 닫는 것에 대해 걱정할 필요가 없습니다. 파일과 관련된 모든 것이 한 번에 모두 읽 히면 좋은 선택입니다.


29

다음은 파일에 대한 목록 이해를 사용하는 또 다른 옵션입니다.

lines = [line.rstrip() for line in open('file.txt')]

대부분의 작업이 Python 인터프리터 내에서 수행되므로보다 효율적인 방법이어야합니다.


10
rstrip()잠재적으로 ; 뿐만 아니라 모든 후행 공백을 제거 합니다 \n. 사용하십시오 .rstrip('\n').
mklement0

이것은 또한 모든 파이썬 구현에서 읽은 후에 파일이 닫히는 것을 보장하지는 않습니다 (주 파이썬 구현 인 CPython에서는 그렇지 만).
Mark Amery

1
대부분의 작업이 Python 인터프리터 내에서 수행되므로보다 효율적인 방법이어야합니다. 그게 무슨 뜻이야?
AMC

28
f = open("your_file.txt",'r')
out = f.readlines() # will append in the list out

이제 변수 출력은 원하는 것의 목록 ​​(배열)입니다. 당신은 할 수 있습니다 :

for line in out:
    print (line)

또는:

for line in f:
    print (line)

동일한 결과를 얻을 수 있습니다.


27

Python 2 및 Python 3으로 텍스트 파일을 읽고 씁니다. 그것은 유니 코드와 함께 작동

#!/usr/bin/env python3
# -*- coding: utf-8 -*-

# Define data
lines = ['     A first string  ',
         'A Unicode sample: €',
         'German: äöüß']

# Write text file
with open('file.txt', 'w') as fp:
    fp.write('\n'.join(lines))

# Read text file
with open('file.txt', 'r') as fp:
    read_lines = fp.readlines()
    read_lines = [line.rstrip('\n') for line in read_lines]

print(lines == read_lines)

주의 사항 :

  • with소위 컨텍스트 관리자 입니다. 열린 파일이 다시 닫힙니다.
  • 여기에서 공백을 제거하기 때문에 단순히 재현 .strip()하거나 .rstrip()재현하지 못하는 모든 솔루션 lines.

일반적인 파일 엔딩

.txt

고급 파일 쓰기 / 읽기

응용 프로그램의 경우 다음이 중요 할 수 있습니다.

  • 다른 프로그래밍 언어로 지원
  • 읽기 / 쓰기 성능
  • 소형화 (파일 크기)

참조 : 데이터 직렬화 형식 비교

구성 파일을 만드는 방법을 찾고 있다면 짧은 기사 Configuration files in Python 을 읽으십시오 .


26

다른 옵션은 numpy.genfromtxt예를 들면 다음과 같습니다.

import numpy as np
data = np.genfromtxt("yourfile.dat",delimiter="\n")

그러면 data파일에있는만큼의 행 이 있는 NumPy 배열 이 만들어 집니다.


25

명령 행 또는 stdin에서 파일을 읽으려면 fileinput모듈 을 사용할 수도 있습니다 .

# reader.py
import fileinput

content = []
for line in fileinput.input():
    content.append(line.strip())

fileinput.close()

파일을 다음과 같이 전달하십시오.

$ python reader.py textfile.txt 

자세한 내용은 여기를 참조하십시오 : http://docs.python.org/2/library/fileinput.html


20

가장 간단한 방법

간단한 방법은 다음과 같습니다.

  1. 전체 파일을 문자열로 읽습니다.
  2. 줄을 한 줄씩 나눕니다

한 줄에, 그것은 줄 것이다 :

lines = open('C:/path/file.txt').read().splitlines()

그러나 이것은 메모리에 2 가지 버전의 내용을 저장하기 때문에 매우 비효율적입니다 (아마 작은 파일의 경우 큰 문제는 아니지만 여전히). 감사합니다. Mark Amery.

두 가지 쉬운 방법이 있습니다.

  1. 파일을 반복자로 사용
lines = list(open('C:/path/file.txt'))
# ... or if you want to have a list without EOL characters
lines = [l.rstrip() for l in open('C:/path/file.txt')]
  1. Python 3.4 이상 pathlib을 사용하는 경우 프로그램의 다른 작업에 사용할 수있는 파일 경로를 만드는 것이 좋습니다 .
from pathlib import Path
file_path = Path("C:/path/file.txt") 
lines = file_path.read_text().split_lines()
# ... or ... 
lines = [l.rstrip() for l in file_path.open()]

이것은 나쁜 접근법입니다. 우선, 호출 .read().splitlines()은 단순히 호출하는 것보다 "간단한"방법이 아닙니다 .readlines(). 다른 하나는 메모리 비효율적입니다. 불필요하게 파일 내용의 두 버전 (에 의해 반환 된 단일 문자열 .read()과에 의해 반환 된 문자열 목록 splitlines())을 메모리에 한 번에 저장합니다.
Mark Amery

@MarkAmery True. 이것을 강조해 주셔서 감사합니다. 내 답변을 업데이트했습니다.
Jean-Francois T.

14

splitlines () 함수를 사용하십시오. 다음은 예입니다.

inp = "file.txt"
data = open(inp)
dat = data.read()
lst = dat.splitlines()
print lst
# print(lst) # for python 3

출력에는 라인 목록이 있습니다.


를 사용하는 것과 비교하여 메모리가 비효율적 .readlines()입니다. 이렇게하면 파일 내용의 복사본 두 개가 한 번에 메모리에 저장됩니다 (하나는 거대한 문자열로, 하나는 줄 목록으로).
Mark Amery

11

매우 크거나 큰 파일에 직면하고 더 빨리 읽고 싶다면 (Topcoder / Hackerrank 코딩 경쟁에 있다고 상상해보십시오), 한 번에 한 번에 메모리 버퍼에 상당히 큰 줄을 읽을 수 있습니다. 파일 수준에서 한 줄씩 반복하십시오.

buffersize = 2**16
with open(path) as f: 
    while True:
        lines_buffer = f.readlines(buffersize)
        if not lines_buffer:
            break
        for line in lines_buffer:
            process(line)

프로세스 (라인)는 무엇을합니까? 그러한 변수가 정의되어 있지 않다는 오류가 발생합니다. 가져 오기가 필요하고 multiprocessing.Process를 가져 오려고했지만 추측하지는 않습니다. 좀 더 자세히 설명해 주시겠습니까? 감사합니다
Newskooler

1
process(line)데이터를 처리하기 위해 구현해야하는 기능입니다. 예를 들어, 해당 행 대신을 사용 print(line)하면 lines_buffer에서 각 행을 인쇄합니다.
Khanal

f.readlines (buffersize)는 불변 버퍼를 반환합니다. 버퍼를 직접 읽으려면 readinto () 함수를 사용해야합니다. 나는 훨씬 더 빠를 것이다.
David Dehghan

7

몇 가지 추가 이점으로이를 수행하는 가장 쉬운 방법은 다음과 같습니다.

lines = list(open('filename'))

또는

lines = tuple(open('filename'))

또는

lines = set(open('filename'))

의 경우 set라인 순서가 유지되지 않고 중복 된 라인을 제거한다는 것을 기억해야합니다.

아래에 @MarkAmery 의 중요한 보충 자료를 추가했습니다 .

.close파일 객체를 호출 하거나 with명령문을 사용 하지 않기 때문에 일부 Python 구현 에서는 파일을 읽은 후에 파일이 닫히지 않고 프로세스에서 열린 파일 핸들이 누출됩니다 .

에서 CPython의 (일반 파이썬 대부분의 사람들이 사용하는 구현), 파일 객체가 즉시 가비지 수집 얻을 것이다이 파일을 닫습니다 때문에이 문제가 아니지만, 그럼에도 불구하고 일반적으로 같은 것을 할 수있는 가장 좋은 방법을 간주 :

with open('filename') as f: lines = list(f) 

사용중인 Python 구현에 관계없이 파일이 닫히도록하십시오 .


1
.close파일 객체를 호출 하거나 with명령문을 사용 하지 않기 때문에 일부 Python 구현에서는 파일을 읽은 후에 파일이 닫히지 않을 수 있으며 프로세스에서 열린 파일 핸들이 누출됩니다. CPython의 (대부분의 사람들이 사용하는 일반 파이썬 구현)에서 파일 개체가 즉시 가비지 수집 얻을 것이다이 파일을 닫습니다 때문에이 문제가 아니지만, 그럼에도 불구하고 일반적으로 같은 것을 할 최선의 방법을 간주 with open('filename') as f: lines = list(f)것을 보장하기를 사용중인 Python 구현에 관계없이 파일이 닫힙니다.
Mark Amery

@MarkAmery에 대한 귀하의 큰 의견에 감사드립니다! 정말 감사.
simhumileco

1
@simhumileco 왜 최상의 (올바른) 솔루션이 지속됩니까?
AMC

@AMC는 먼저 가장 간단한 방법과 추론의 일관성을 보여주기를 원했기 때문입니다.
simhumileco

게다가, 나는 대답이 짧고 읽기 쉽도록 만들어지기를 바랍니다.
simhumileco

4

이것을 사용하십시오 :

import pandas as pd
data = pd.read_csv(filename) # You can also add parameters such as header, sep, etc.
array = data.values

data데이터 프레임 유형이며 값을 사용하여 ndarray를 가져옵니다. 을 사용하여 목록을 얻을 수도 있습니다 array.tolist().


pandas.read_csv()CSV 데이터 를 읽기위한 것입니다. 여기서는 어떻게 적절합니까?
AMC

4

개요 및 요약

를 사용하여 객체 filename에서 파일을 처리하거나을 사용하여 Path(filename)직접 open(filename) as f다음 중 하나를 수행하십시오.

  • list(fileinput.input(filename))
  • 를 사용하여 with path.open() as f전화f.readlines()
  • list(f)
  • path.read_text().splitlines()
  • path.read_text().splitlines(keepends=True)
  • 반복 fileinput.input또는 flist.append 한 번에 각 라인 하나
  • f바운드로 전달list.extend 메서드에
  • 사용 f지능형리스트에

아래에서 각각의 유스 케이스를 설명합니다.

파이썬에서 파일을 한 줄씩 읽는 방법은 무엇입니까?

이것은 훌륭한 질문입니다. 먼저 샘플 데이터를 만들어 봅시다 :

from pathlib import Path
Path('filename').write_text('foo\nbar\nbaz')

파일 객체는 게으른 반복자이므로 반복하십시오.

filename = 'filename'
with open(filename) as f:
    for line in f:
        line # do something with the line

또는 파일이 여러 개인 경우 fileinput.input다른 지연 반복기를 사용하십시오. 하나의 파일로 :

import fileinput

for line in fileinput.input(filename): 
    line # process the line

또는 여러 파일의 경우 파일 이름 목록을 전달하십시오.

for line in fileinput.input([filename]*2): 
    line # process the line

다시, f그리고 fileinput.input모두가 위 / 게으른 반복자를 돌려줍니다. 반복자를 한 번만 사용할 수 있으므로 자세한 정보를 피하면서 기능 코드를 제공하려면 fileinput.input(filename)여기에서 제안하는 부분 이 약간 더 간결 합니다.

파이썬에서 파일을 한 줄씩 목록으로 읽는 방법은 무엇입니까?

아 그러나 당신은 어떤 이유로 목록에 그것을 원하십니까? 가능하다면 피할 것입니다. 그러나 주장한다면 ...의 결과 fileinput.input(filename)list다음으로 전달하십시오 .

list(fileinput.input(filename))

또 다른 직접적인 대답은 call f.readlines이며 파일의 내용을 반환합니다 (선택적인 hint문자 수까지 가능). 까지 가능). 여러 목록으로 나눌 수 있습니다.

이 파일 객체에는 두 가지 방법이 있습니다. 한 가지 방법은 파일 이름을 open내장 으로 전달하는 것입니다 .

filename = 'filename'

with open(filename) as f:
    f.readlines()

또는 pathlib모듈 에서 새로운 Path 객체를 사용합니다 (매우 좋아했으며 여기서부터 사용할 것입니다).

from pathlib import Path

path = Path(filename)

with path.open() as f:
    f.readlines()

list 또한 파일 반복자를 소비하고 목록을 반환합니다.

with path.open() as f:
    list(f)

분할하기 전에 전체 텍스트를 메모리에 단일 문자열로 읽는 것이 마음에 들지 않으면 Path객체와 splitlines()문자열 메서드를 사용하여 단일 라이너로 수행 할 수 있습니다 . 기본적으로 줄 splitlines바꾸기를 제거합니다.

path.read_text().splitlines()

줄 바꿈을 유지하려면 다음을 전달하십시오 keepends=True.

path.read_text().splitlines(keepends=True)

파일을 한 줄씩 읽고 각 줄을 목록 끝에 추가하고 싶습니다.

이제 몇 가지 방법으로 최종 결과를 쉽게 보여 주었으므로 이것은 약간 어리석은 일입니다. 그러나 목록을 작성할 때 회선을 필터링하거나 조작해야 할 수도 있으므로이 요청을 유머 화하십시오.

를 사용 list.append하면 추가하기 전에 각 줄을 필터링하거나 조작 할 수 있습니다.

line_list = []
for line in fileinput.input(filename):
    line_list.append(line)

line_list

사용하는 list.extend것이 조금 더 직접적이며 기존 목록이있는 경우 유용 할 수 있습니다.

line_list = []
line_list.extend(fileinput.input(filename))
line_list

또는 관용적으로, 우리는 대신 목록 이해를 사용하고 원하는 경우 그 안에 매핑하고 필터링 할 수 있습니다.

[line for line in fileinput.input(filename)]

또는 더 직접적으로 원을 닫으려면 선을 조작하지 않고 직접 목록을 전달하여 새 목록을 직접 만드십시오.

list(fileinput.input(filename))

결론

파일에서 목록으로 줄을 가져 오는 많은 방법을 보았지만 대량의 데이터를 목록으로 구체화하지 말고 가능한 경우 Python의 지연 반복을 사용하여 데이터를 처리하는 것이 좋습니다.

즉, fileinput.input또는을 선호하십시오 with path.open() as f.


4

문서에 빈 줄이있는 경우 내용을 읽고 filter빈 문자열 요소를 방지하기 위해 통과시킵니다.

with open(myFile, "r") as f:
    excludeFileContent = list(filter(None, f.read().splitlines()))

1
이것은 비유 의적입니다. 조심하십시오.
AMC

3

NumPy에서 loadtxt 명령을 사용할 수도 있습니다. genfromtxt보다 적은 조건을 확인하므로 속도가 더 빠를 수 있습니다.

import numpy
data = numpy.loadtxt(filename, delimiter="\n")

2

나는 다음을 사용하고 싶다. 즉시 줄을 읽습니다.

contents = []
for line in open(filepath, 'r').readlines():
    contents.append(line.strip())

또는 목록 이해 사용하기 :

contents = [line.strip() for line in open(filepath, 'r').readlines()]

2
에 대한 불필요 readlines(), 심지어 메모리 페널티가 발생합니다. (텍스트) 파일을 반복하면 각 줄이 차례로 표시되므로 간단히 제거 할 수 있습니다.
Eric O Lebigot

2
with명령문을 사용 하여 파일을 열고 내재적으로 닫아야합니다.
Aran-Fey

2

아래 언급 된 방법 중 하나를 시도합니다. 내가 사용하는 예제 파일의 이름은 dummy.txt입니다. 여기 에서 파일을 찾을 수 있습니다 . 파일이 코드와 동일한 디렉토리에 있다고 가정합니다 ( fpath적절한 파일 이름과 폴더 경로를 포함하도록 변경할 수 있습니다 ).

아래 언급 된 두 가지 예에서 원하는 목록은로 제공됩니다 lst.

1.> 첫 번째 방법 :

fpath = 'dummy.txt'
with open(fpath, "r") as f: lst = [line.rstrip('\n \t') for line in f]

print lst
>>>['THIS IS LINE1.', 'THIS IS LINE2.', 'THIS IS LINE3.', 'THIS IS LINE4.']

2.> 에서 두 번째 방법은 , 하나는 사용할 수 csv.reader 파이썬 표준 라이브러리에서 모듈 :

import csv
fpath = 'dummy.txt'
with open(fpath) as csv_file:
    csv_reader = csv.reader(csv_file, delimiter='   ')
    lst = [row[0] for row in csv_reader] 

print lst
>>>['THIS IS LINE1.', 'THIS IS LINE2.', 'THIS IS LINE3.', 'THIS IS LINE4.']

두 가지 방법 중 하나를 사용할 수 있습니다. lst두 가지 방법으로 제작 시간 이 거의 동일합니다.


1
두 번째 방법의 장점은 무엇입니까? 왜 대소 문자 (구분 기호 및 따옴표)를 추가하는 추가 라이브러리를 호출해야합니까?
찰리 하딩

에 대한 delimiter=' '논쟁 은 무엇입니까 ?
AMC

2

다음은 파일 I / O를 단순화하는 데 사용 하는 Python (3) 도우미 라이브러리 클래스입니다.

import os

# handle files using a callback method, prevents repetition
def _FileIO__file_handler(file_path, mode, callback = lambda f: None):
  f = open(file_path, mode)
  try:
    return callback(f)
  except Exception as e:
    raise IOError("Failed to %s file" % ["write to", "read from"][mode.lower() in "r rb r+".split(" ")])
  finally:
    f.close()


class FileIO:
  # return the contents of a file
  def read(file_path, mode = "r"):
    return __file_handler(file_path, mode, lambda rf: rf.read())

  # get the lines of a file
  def lines(file_path, mode = "r", filter_fn = lambda line: len(line) > 0):
    return [line for line in FileIO.read(file_path, mode).strip().split("\n") if filter_fn(line)]

  # create or update a file (NOTE: can also be used to replace a file's original content)
  def write(file_path, new_content, mode = "w"):
    return __file_handler(file_path, mode, lambda wf: wf.write(new_content))

  # delete a file (if it exists)
  def delete(file_path):
    return os.remove() if os.path.isfile(file_path) else None

그런 다음 다음 FileIO.lines과 같이 함수 를 사용하십시오 .

file_ext_lines = FileIO.lines("./path/to/file.ext"):
for i, line in enumerate(file_ext_lines):
  print("Line {}: {}".format(i + 1, line))

(가) 기억 mode( "r"기본적으로) 및 filter_fn매개 변수 (기본적으로 빈 줄을 검사)는 선택 사항입니다.

read, writedelete메소드를 제거 하고을 그대로 두거나 FileIO.lines이라는 별도의 메소드로 바꿀 수도 read_lines있습니다.


lines = FileIO.lines(path)정말 충분히 간단보다 with open(path) as f: lines = f.readlines()이 도우미의 존재를 정당화하기 위해? 통화 당 17자를 저장합니다. (대부분의 경우 성능 및 메모리 이유로 인해 줄을 목록으로 읽는 대신 파일 객체를 직접 반복하여 사용하고 싶기 때문에 자주 사용하고 싶지는 않습니다!) 종종 작은 유틸리티 함수를 만드는 팬이지만, 이것은 표준 라이브러리로 이미 짧고 쉬운 것을 작성하는 새로운 방법을 불필요하게 만드는 것처럼 느껴집니다.
Mark Amery

@MarkAmery가 말한 것 외에도 왜 이것을 위해 클래스를 사용합니까?
AMC

1

명령 줄 버전

#!/bin/python3
import os
import sys
abspath = os.path.abspath(__file__)
dname = os.path.dirname(abspath)
filename = dname + sys.argv[1]
arr = open(filename).read().split("\n") 
print(arr)

로 실행 :

python3 somefile.py input_file_name.txt
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.