Як прочитати файл рядок за списком?


2027

Як я читаю кожен рядок файлу в Python і зберігаю кожний рядок як елемент у списку?

Я хочу прочитати файл за рядком і додати кожен рядок до кінця списку.

Відповіді:


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
Не використовуйте file.readlines()в for-loop, достатньо самого файлового об’єкта:lines = [line.rstrip('\n') for line in file]
jfs

88
У випадку, коли ви працюєте з Big Data, використання readlines()не дуже ефективно, оскільки це може призвести до пам'яті MemoryError . У цьому випадку краще перебрати файл, використовуючи for line in f:та працюючи з кожною lineзмінною.
DarkCygnus

7
Я перевіряв профіль пам'яті різними способами, наведеними у відповідях, використовуючи процедуру, згадану тут . Використання пам'яті набагато краще , коли кожен рядок зчитується з файлу і обробляються, як це було запропоновано @DevShark тут . Утримувати всі рядки в об'єкті колекції - це не дуже гарна ідея, якщо пам'ять є обмеженням або файл великий. Час виконання подібний в обох підходах.
Tirtha R

6
Крім того, .rstrip()буде працювати трохи швидше, якщо ви знімете пробіли з кінців рядків.
Gringo Suave

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(), що видаляє нові рядки
Марк

Чи є друга версія з for line in open(filename)безпечною? Тобто, чи буде файл автоматично закритий?
бекко

2
Найкраще читати файл один рядок, а не читати весь файл в пам'яті відразу. Це не дуже масштабує великі вхідні файли. Дивіться нижче відповідь від Роберта.
Бред Хайн

1
lines = [x.rstrip('\n') for x in open('data\hsf.txt','r')]Якщо я пишу так, як я можу закрити файл після читання?
Раміса Анжум Адіті

2
Так, до того, що тут роблять інші, хоча це не "найкраща практика" використовувати openбез менеджера контексту (або якогось іншого гарантованого способу його закрити), це насправді не один із таких випадків - коли об'єкт не має більше посилань до нього буде зібрано сміття та закритий файл, що має відбутися негайно після помилки чи ні, коли розуміння списку буде виконано обробкою.
Аарон Холл

579

Це більш явно, ніж потрібно, але робить те, що ви хочете.

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

18
Я віддаю перевагу цій відповіді, оскільки не потрібно завантажувати весь файл у пам'ять (у цьому випадку він все ще додається array, але можуть бути й інші обставини). Звичайно, для великих файлів такий підхід може полегшити проблеми.
ЙоханнесB

1
Додавання до масиву відбувається повільно. Я не можу придумати випадок використання, коли це найкраще рішення.
Еліас Стреле

@haccks це краще, тому що він не завантажує весь файл у пам'ять або є більше?
OrigamiEye

4
Примітка. Це рішення не позбавляє нових рядків.
AMC

1
Це рішення дійсно завантажує весь файл у пам'ять. Я не знаю, чому люди думають, що це не так.
andrebrait

274

Це дасть "масив" рядків з файлу.

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

openповертає файл, який можна повторити. Коли ви повторюєте файл, ви отримуєте рядки з цього файлу. tupleможе взяти ітератор і створити екземпляр кортежу для нього від ітератора, який ви йому надаєте. lines- кортеж, створений із рядків файлу.


31
Спробуйте lines = open(filename).read().split('\n')натомість @MarshallFarrier .
Noctis Skytower

16
це закриває файл?
Вануан

5
@Vanuan Оскільки після запуску рядка не залишилося посилання на файл, деструктор повинен автоматично закрити файл.
Noctis Skytower

30
@NoctisSkytower я вважаю lines = open(filename).read().splitlines()трохи чистішим, і я вважаю, що він також краще обробляє закінчення рядків DOS.
jaynp

8
@ mklement0 Припускаючи файл з 1000 рядків, а listзаймає приблизно 13,22% більше місця, ніж a tuple. Результати приходять from sys import getsizeof as g; i = [None] * 1000; round((g(list(i)) / g(tuple(i)) - 1) * 100, 2). Створення tupleзайме приблизно 4,17% більше часу, ніж створення 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 разів. Моє рішення надає перевагу простору над швидкістю, коли потреба у незмінності невідома.
Noctis Skytower

194

Якщо ви хочете \nвключити:

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

Якщо ви не хочете \nвключити:

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

168

Відповідно до методів файлових об’єктів Python , найпростіший спосіб перетворення текстового файлу в 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

149

Ви можете просто зробити наступне, як було запропоновано:

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

Зауважте, що у цього підходу є 2 мінуси:

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
Це саме те, що мені було потрібно - і дякую за пояснення недоліків. Як новачок в Python, дивовижно зрозуміти, чому рішення - це рішення. Ура!
Ефекс

5
Подумайте трохи більше Кори. Ви дійсно хочете, щоб ваш комп'ютер читав кожен рядок, не роблячи нічого з цими рядками? Звичайно, ви можете усвідомити, що завжди потрібно так чи інакше обробляти їх.
DevShark

5
Завжди потрібно щось робити з лініями. Це може бути таким же простим, як друк рядків або їх підрахунок. Немає значення в тому, щоб ваш процес читав рядки в пам'яті, але нічого з цим не робити.
DevShark

2
Вам завжди потрібно щось робити з ними. Я думаю, що ви намагаєтеся зробити те, що ви, можливо, захочете застосувати функцію до них усі одразу, а не по черзі. І справді іноді так буває. Але з точки зору пам’яті це дуже неефективно, і це заважає читати файли, якщо його слід більший, ніж ваш Ram. Ось чому зазвичай загальні аналізатори функціонують так, як я описав.
DevShark

2
@PierreOcinom це правильно. Зважаючи на те, що файл відкрито в режимі лише для читання, ви не змогли змінити оригінальний файл з кодом вище. Щоб відкрити файл як для читання, так і для запису, використовуйтеopen('file_path', 'r+')
DevShark

62

Дані в список

Припустимо, що у нас є текстовий файл з нашими даними, як у наступних рядках,

Вміст текстового файлу:

line 1
line 2
line 3
  • Відкрийте cmd у тому самому каталозі (клацніть правою кнопкою миші та виберіть cmd або PowerShell)
  • Виконати pythonі в перекладачі написати:

Сценарій 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']

Або:

>>> y = [x.rstrip() for x in open("my_file.txt")]
>>> y
['line 1','line 2','line 3']


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

with open('testodiprova.txt', 'r', encoding='utf-8') as file:
  file = file.readlines()
  print(file)

це encoding="utf-8"потрібно?
Mausy5043

@ Mausy5043 ні, але коли ви читаєте текстовий файл, ви можете мати дивного характеру (особливо італійською мовою)
Giovanni G. PY

1
read().splitlines()вам надає Python: це просто readlines()(що, мабуть, швидше, оскільки він менш марнотратний).
Ерік О Лебігот

43

Щоб прочитати файл у списку, потрібно виконати три дії:

  • Відкрийте файл
  • Прочитайте файл
  • Зберігати вміст як список

На щастя, Python дуже легко робить це, тому найкоротший спосіб прочитати файл у список:

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)

Зверніть увагу, що розширення файлу потрібно вказати. Це особливо важливо для користувачів Windows , так як розширення файлів , як .txtі .docт.д. приховані за замовчуванням при перегляді в провіднику.

Другий аргумент - 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кидає виняток. Ви можете уникнути цього, використовуючи tryта finally:

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

Однак Python пропонує менеджери контексту, які мають гарніший синтаксис (але openвін майже ідентичний вище tryта finallyвище):

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

Останній підхід - рекомендований підхід до відкриття файлу в Python!

Читання файлу

Гаразд, ви відкрили файл, тепер як його читати?

openФункція повертає fileоб'єкт , і він підтримує протокол ітерації пітонів. Кожна ітерація надасть вам рядки:

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

Це надрукує кожен рядок файлу. Зауважте, що кожен рядок буде містити символ нового рядка \nв кінці (можливо, ви захочете перевірити, чи ваш Python побудований із підтримкою універсальної лінії для нових рядків - інакше ви також можете мати \r\nв Windows чи \rна Mac як нові рядки). Якщо ви не хочете, ви можете просто видалити останній символ (або два останні символи в 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), які .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об'єкта за замовчуванням повертає a 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()але якщо ви хочете обробити рядки перед тим, як зберігати їх у списку, я б рекомендував просте розуміння списку.

Останній підхід - рекомендований підхід до відкриття файлу в Python! Чому він останній? Невже переважна більшість людей просто перегляне перші кілька рядків відповіді, перш ніж продовжувати?
AMC

@AMC Я не дуже замислювався над цим, коли писав відповідь. Як ви думаєте, я повинен поставити це у верхній частині відповіді?
MSeifert

Це може бути найкраще, так. Я також щойно помітив, що ви згадуєте Python 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, оскільки вони є ітерабельними, ефективними та гнучкими. У вашому випадку бажаною метою є виведення кожного рядка текстового файлу в окремий елемент. Для цього ми будемо використовувати метод 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]
  • Вихід (різний вигляд через символи unicode):
     ['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

Це також не гарантує, що файл буде закритий після читання у всіх реалізаціях Python (хоча в CPython, головна реалізація Python, це буде).
Марк Амері

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; він працює з Unicode

#!/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

Більш вдосконалене написання / читання файлів

Для вашої заявки може бути важливим наступне:

  • Підтримка іншими мовами програмування
  • Виконання читання / письма
  • Компактність (розмір файлу)

Дивіться також: Порівняння форматів серіалізації даних

Якщо ви шукаєте спосіб створення файлів конфігурації, ви можете прочитати мою коротку статтю Конфігураційні файли в 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 версії вмісту в пам'яті (мабуть, це не велика проблема для невеликих файлів, але все ж). [Спасибі Марку Амерді].

Є два простіших способи:

  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()) відразу в пам'яті.
Марк Амері

@MarkAmery True. Дякуємо, що виділили це. Я оновив свою відповідь.
Жан-Франсуа Т.

14

Просто використовуйте функції splitlines (). Ось приклад.

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

У висновку у вас буде список рядків.


Пам'ять неефективна порівняно з використанням .readlines(). Це ставить дві копії вмісту файлу одразу в пам’ять (одна - як один величезний рядок, друга - як список рядків).
Марк Амері

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)

що робить процес (рядок)? Я отримую помилку, що не існує такої змінної. Я думаю, що потрібно щось імпортувати, і я намагався імпортувати багатопроцесорний процес. Але я думаю, це не все. Чи можете ви, будь ласка, докладно? Спасибі
Newskooler

1
process(line)- це функція, яку потрібно реалізувати для обробки даних. наприклад, замість цього рядка, якщо ви використовуєте print(line), він буде надрукувати кожен рядок із рядка_буфера.
Ханал

f.readlines (буферний розмір) повертає незмінний буфер. якщо ви хочете безпосередньо читати у своєму буфері, вам потрібно скористатися функцією readinto (). Я стану набагато швидшим.
Девід Деган

7

Найпростіші способи зробити це з деякими додатковими перевагами:

lines = list(open('filename'))

або

lines = tuple(open('filename'))

або

lines = set(open('filename'))

У випадку з set, ми повинні пам’ятати, що в нас немає збереженого порядку рядків і позбутися дублюваних рядків.

Нижче я додав важливу добавку від @MarkAmery :

Оскільки ви не викликаєте .closeоб’єкт файлу і не використовуєте withоператор, у деяких реалізаціях Python файл може не закритися після читання, і ваш процес витіче з відкритої ручки файлу .

У CPython (звичайна реалізація Python, якою користується більшість людей), це не проблема, оскільки об’єкт файлу негайно отримає зібраний сміття, і це закриє файл, але тим не менш, як правило, найкращою практикою є щось подібне :

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

щоб закрити файл незалежно від того, яку програму Python ви використовуєте.


1
Оскільки ви не викликаєте .closeоб’єкт файлу і не використовуєте withоператор, у деяких реалізаціях Python файл може не закритися після читання, і ваш процес витіче з відкритої ручки файлу. У CPython (звичайна реалізація Python, якою користується більшість людей), це не проблема, оскільки об’єкт файлу негайно отримає зібраний сміття, і це закриє файл, але, тим не менш, загалом найкращою практикою вважається робити щось на кшталт with open('filename') as f: lines = list(f)того файл закривається незалежно від того, яку реалізацію Python ви використовуєте.
Марк Амері

Дякую за ваш чудовий коментар @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

Конспект та резюме

За допомогою a 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або fі list.appendкожен рядок по одному за раз
  • перейти fдо зв'язаного list.extendметоду
  • використання fв розумінні списку

Я пояснюю приклад використання для кожного нижче.

Як я можу прочитати файл у рядку в Python?

Це відмінне запитання. Спочатку створимо кілька прикладних даних:

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)де зараз.

Як в Python я можу прочитати файл рядок за рядком у списку?

Ах, але ви хочете це в списку чомусь? Я б уникну цього, якщо можливо. Але якщо ви наполягаєте ... просто передати результат fileinput.input(filename)в list:

list(fileinput.input(filename))

Інша пряма відповідь - дзвінок f.readlines, який повертає вміст файлу (до необов'язкової hintкількості символів, щоб ви могли поділити це на декілька списків таким чином).

Ви можете дістатися до цього файлового об’єкта двома способами. Один із способів - передати ім'я файлу openвбудованому:

filename = 'filename'

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

або використовуючи новий об'єкт Path з pathlibмодуля (який мені вже дуже подобається, і я буду використовувати тут):

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

Ви також можете використовувати команду loadtxt в NumPy. Це перевіряє менше умов, ніж 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(), яка навіть несе штрафну пам'ять. Ви можете просто його видалити, оскільки повторення над (текстовим) файлом дає по черзі кожен рядок.
Ерік О Лебігот

2
Ви повинні використовувати withоператор, щоб відкрити (та неявно закрити) файл.
Аран-Фей

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 з стандартної бібліотеки Python :

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

Ось бібліотечний клас бібліотеки 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, writeі deleteметоди, і просто залишити FileIO.lines, або навіть перетворити його в окремий метод, який називається read_lines.


Є чи на lines = FileIO.lines(path)самому ділі досить простіше , ніж with open(path) as f: lines = f.readlines()виправдати існування цього помічника в? Ви заощаджуєте, наприклад, 17 символів на дзвінок. (І більшу частину часу, з міркувань продуктивності та пам’яті, ви хочете перенести цикл на файл-об’єкт безпосередньо, а не читати його рядки у списку, так що ви навіть не хочете цим часто користуватися!) часто прихильник створення невеликих функцій утиліти, але мені здається, що це просто зайве створення нового способу написати щось, що вже є коротким і простим за допомогою стандартної бібліотеки.
Марк Амері

Окрім того, що сказав @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
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.