Jak czytać każdą linię pliku w Pythonie i przechowywać każdą linię jako element na liście?
Chcę czytać plik linia po linii i dołączać każdą linię na końcu listy.
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]
file.readlines()
wfor
pętli, wystarczy sam obiekt pliku:lines = [line.rstrip('\n') for line in file]
readlines()
nie jest bardzo wydajne, ponieważ może spowodować błąd MemoryError . W takim przypadku lepiej jest iterować plik przy użyciufor line in f:
i pracy z każdąline
zmienną..rstrip()
nieco szybciej, jeśli usuwasz białe znaki z końców linii.with open(filename) as f: content = [i.strip() for i in f.readlines()]
Zobacz Input i Ouput :
lub z usunięciem znaku nowej linii:
źródło
f.read().splitlines()
, który usuwa nowe wierszefor line in open(filename)
bezpieczna? Czy plik zostanie automatycznie zamknięty?lines = [x.rstrip('\n') for x in open('data\hsf.txt','r')]
Jeśli piszę w ten sposób, jak mogę zamknąć plik po przeczytaniu?open
bez menedżera kontekstu (lub innego gwarantowanego sposobu zamknięcia go), to nie jest tak naprawdę jeden z tych przypadków - gdy obiekt nie ma już żadnych odniesień zostanie do niej wyrzucony śmieci, a plik zamknięty, co powinno nastąpić natychmiast po błędzie, czy nie, kiedy przetwarzanie listy zostanie zakończone.Jest to bardziej wyraźne niż to konieczne, ale robi to, co chcesz.
źródło
array
, ale mogą istnieć inne okoliczności). Z pewnością w przypadku dużych plików takie podejście może złagodzić problemy.To da „tablicę” linii z pliku.
open
zwraca plik, który można powtórzyć. Gdy iterujesz po pliku, otrzymujesz wiersze z tego pliku.tuple
może pobrać iterator i utworzyć dla niego instancję krotki z iteratora, który mu podałeś.lines
to krotka utworzona z linii pliku.źródło
lines = open(filename).read().split('\n')
zamiast tego.lines = open(filename).read().splitlines()
jest trochę czystszy i uważam, że lepiej obsługuje zakończenia linii DOS.list
zajmuje około 13,22% więcej miejsca niż atuple
. Wyniki pochodzą zfrom sys import getsizeof as g; i = [None] * 1000; round((g(list(i)) / g(tuple(i)) - 1) * 100, 2)
. Utworzenietuple
zajmuje około 4,17% więcej czasu niż utworzenielist
(z odchyleniem standardowym 0,16%). Wyniki pochodzą z uruchomieniafrom timeit import timeit as t; round((t('tuple(i)', 'i = [None] * 1000') / t('list(i)', 'i = [None] * 1000') - 1) * 100, 2)
30 razy. Moje rozwiązanie preferuje przestrzeń nad prędkością, gdy potrzeba zmienności jest nieznana.Jeśli chcesz
\n
uwzględnić:Jeśli nie chcesz
\n
uwzględniać:źródło
Zgodnie z Python's Methods of File Objects , najprostszym sposobem konwersji pliku tekstowego na plik
list
jest:Jeśli potrzebujesz tylko iterować linie wiersza pliku tekstowego, możesz użyć:
Stara odpowiedź:
Korzystanie
with
ireadlines()
:Jeśli nie zależy ci na zamknięciu pliku, ten jednowierszowy działa:
Tradycyjny sposób:
źródło
Możesz po prostu wykonać następujące czynności, jak sugerowano:
Zauważ, że to podejście ma 2 wady:
1) Wszystkie linie zapisujesz w pamięci. W ogólnym przypadku jest to bardzo zły pomysł. Plik może być bardzo duży i może zabraknąć pamięci. Nawet jeśli nie jest duży, to po prostu strata pamięci.
2) Nie pozwala to na przetwarzanie każdej linii podczas ich czytania. Więc jeśli przetworzysz swoje linie po tym, nie będzie to wydajne (wymaga dwóch przejść zamiast jednego).
Lepszym podejściem do ogólnego przypadku byłoby:
Gdzie definiujesz swoją funkcję procesu w dowolny sposób. Na przykład:
(Wdrożenie
Superman
klasy jest dla ciebie ćwiczeniem).Będzie to działało ładnie dla każdego rozmiaru pliku i przejrzysz plik w ciągu zaledwie 1 przejścia. Tak zwykle działają ogólne parsery.
źródło
open('file_path', 'r+')
Dane do listy
Załóżmy, że mamy plik tekstowy z naszymi danymi, jak w poniższych wierszach,
Treść pliku tekstowego:
python
iw interprecie napisz:Skrypt Pythona:
Za pomocą append:
Lub:
Lub:
Lub:
źródło
encoding="utf-8"
wymagane?read().splitlines()
jest dostarczany przez Python: jest po prostureadlines()
(co jest prawdopodobnie szybsze, ponieważ jest mniej marnotrawne).Aby odczytać plik na liście, musisz wykonać trzy czynności:
Na szczęście w Pythonie bardzo łatwo jest wykonywać te czynności, dlatego najkrótszym sposobem na odczyt pliku na listę jest:
Dodam jednak więcej wyjaśnień.
Otwieranie pliku
Zakładam, że chcesz otworzyć konkretny plik i nie zajmujesz się bezpośrednio uchwytem pliku (lub uchwytem podobnym do pliku). Najczęściej używaną funkcją do otwierania pliku w Pythonie jest
open
potrzeba jednego argumentu obowiązkowego i dwóch opcjonalnych w Pythonie 2.7:Nazwa pliku powinna być ciągiem reprezentującym ścieżkę do pliku . Na przykład:
Pamiętaj, że należy określić rozszerzenie pliku. Jest to szczególnie ważne dla użytkowników systemu Windows z powodu rozszerzenia plików podoba
.txt
lub.doc
itp ukryte są domyślnie widziana w eksploratorze.Drugim argumentem jest
mode
tor
: domyślnie oznacza to „tylko do odczytu”. Właśnie tego potrzebujesz w swoim przypadku.Ale jeśli naprawdę chcesz utworzyć plik i / lub zapisać plik, potrzebujesz innego argumentu. Jest świetna odpowiedź, jeśli chcesz przegląd .
Aby odczytać plik, możesz go pominąć
mode
lub przekazać:Oba otworzą plik w trybie tylko do odczytu. Jeśli chcesz czytać w pliku binarnym w systemie Windows, musisz użyć trybu
rb
:Na innych platformach
'b'
(tryb binarny) jest po prostu ignorowany.Teraz, gdy pokazałem, jak
open
plik, porozmawiajmy o tym, że zawsze musiszclose
go ponownie. W przeciwnym razie zachowa otwarty uchwyt pliku do pliku, dopóki proces się nie zakończy (lub Python zniszczy uchwyt pliku).Chociaż możesz użyć:
To nie zamknie pliku, gdy coś pomiędzy
open
iclose
zgłasza wyjątek. Można tego uniknąć, używając atry
ifinally
:Jednak Python zapewnia menedżerom kontekście, że mają składnię ładniejszej (ale za
open
to prawie identyczne dotry
ifinally
powyżej):Ostatnie podejście jest zalecanym podejściem do otwarcia pliku w Pythonie!
Czytanie pliku
Ok, otworzyłeś plik, a teraz jak go odczytać?
open
Funkcja zwracafile
obiekt i obsługuje protokół iteracji pytony. Każda iteracja da ci linię:Spowoduje to wydrukowanie każdej linii pliku. Zauważ jednak, że każda linia będzie zawierała znak nowej linii
\n
na końcu (możesz chcieć sprawdzić, czy Twój Python jest zbudowany z uniwersalną obsługą nowej linii - w przeciwnym razie możesz mieć\r\n
na Windowsie lub\r
Macu jako nowe linie). Jeśli nie chcesz, możesz po prostu usunąć ostatni znak (lub dwa ostatnie znaki w systemie Windows):Ale ostatnia linia niekoniecznie ma końcową nową linię, więc nie należy jej używać. Można sprawdzić, czy kończy się on znakiem nowej linii, a jeśli tak, usuń go:
Ale może po prostu usunąć wszystkie spacje (w tym
\n
charakterze) od końca łańcucha , to również usunąć wszystkie inne spływu spacje, więc trzeba być ostrożnym, jeśli są ważne:Jednak jeśli linie kończą się na
\r\n
(Windows „newlines”),.rstrip()
to również zajmie się\r
!Zapisz zawartość jako listę
Teraz, gdy wiesz, jak otworzyć plik i przeczytać go, czas zapisać zawartość na liście. Najprostszą opcją byłoby użycie
list
funkcji:W przypadku, gdy chcesz usunąć końcowe znaki nowej linii, możesz zamiast tego użyć listy:
Lub jeszcze prościej:
.readlines()
metodafile
obiektu domyślnie zwraca alist
z linii:Obejmuje to również końcowe znaki nowego wiersza, jeśli nie chcesz ich, zaleciłbym to
[line.rstrip() for line in f]
podejście, ponieważ pozwala to uniknąć przechowywania dwóch list zawierających wszystkie wiersze w pamięci.Istnieje dodatkowa opcja uzyskania pożądanego wyniku, jednak jest on raczej „nieoptymalny”:
read
pełny plik w ciągu, a następnie dzielony na nowe wiersze:lub:
Te automatycznie zajmują się końcowymi
split
znakami nowej linii, ponieważ postać nie jest uwzględniona. Nie są one jednak idealne, ponieważ plik jest przechowywany jako ciąg znaków i jako lista wierszy w pamięci!Podsumowanie
with open(...) as f
podczas otwierania plików, ponieważ nie musisz samodzielnie zamykać pliku, a plik jest zamykany, nawet jeśli zdarzy się jakiś wyjątek.file
obiekty obsługują protokół iteracji, więc czytanie pliku wiersz po wierszu jest tak proste, jakfor line in the_file_object:
.readlines()
ale jeśli chcesz przetworzyć linie przed zapisaniem ich na liście, zaleciłbym proste zrozumienie listy.źródło
Czysty i pytonowy sposób odczytywania linii pliku na liście
Przede wszystkim powinieneś skupić się na otwieraniu pliku i czytaniu jego zawartości w wydajny i pythoniczny sposób. Oto przykład sposobu, w jaki osobiście NIE preferuję:
Zamiast tego wolę poniższą metodę otwierania plików zarówno do odczytu, jak i zapisu, ponieważ jest ona bardzo czysta i nie wymaga dodatkowego kroku zamykania pliku po zakończeniu korzystania z niego. W poniższym zestawieniu otwieramy plik do odczytu i przypisujemy go do zmiennej „infile”. Po zakończeniu działania kodu w tej instrukcji plik zostanie automatycznie zamknięty.
Teraz musimy skupić się na wprowadzeniu tych danych do listy Python, ponieważ są iterowalne, wydajne i elastyczne. W twoim przypadku pożądanym celem jest przeniesienie każdej linii pliku tekstowego do osobnego elementu. Aby to osiągnąć, użyjemy metody splitlines () w następujący sposób:
Produkt końcowy:
Testowanie naszego kodu:
źródło
Wprowadzony w Pythonie 3.4,
pathlib
ma naprawdę wygodną metodę czytania tekstu z plików, jak następuje:(
splitlines
Wywołanie jest tym, co zmienia go z ciągu zawierającego całą zawartość pliku w listę linii w pliku).pathlib
ma wiele przydatnych udogodnień.read_text
jest miły i zwięzły i nie musisz się martwić otwieraniem i zamykaniem pliku. Jeśli wszystko, co musisz zrobić z plikiem, to przeczytać go za jednym razem, to dobry wybór.źródło
Oto jeszcze jedna opcja, korzystając ze zrozumień list plików;
Powinno to być bardziej wydajne, ponieważ większość pracy jest wykonywana w interpreterie Pythona.
źródło
rstrip()
potencjalnie usuwa wszystkie końcowe białe znaki, nie tylko\n
; użyć.rstrip('\n')
.Teraz zmienna out to lista (tablica) tego, czego chcesz. Możesz albo:
Lub:
Otrzymasz te same wyniki.
źródło
Odczytywanie i zapisywanie plików tekstowych za pomocą Python 2 i Python 3; działa z Unicode
Rzeczy do zauważenia:
with
jest tak zwanym menedżerem kontekstu . Zapewnia to, że otwarty plik jest ponownie zamykany..strip()
lub.rstrip()
nie powiela się,lines
ponieważ usuwają również białą przestrzeń.Typowe zakończenia plików
.txt
Bardziej zaawansowane zapisywanie / odczytywanie plików
W przypadku aplikacji ważne mogą być:
Zobacz także: Porównanie formatów serializacji danych
Jeśli szukasz sposobu na utworzenie plików konfiguracyjnych, możesz przeczytać mój krótki artykuł Pliki konfiguracyjne w Pythonie .
źródło
Inną opcją jest
numpy.genfromtxt
na przykład:Spowoduje to utworzenie
data
tablicy NumPy z tyloma wierszami, ile jest w twoim pliku.źródło
Jeśli chcesz odczytać plik z wiersza poleceń lub ze standardowego wejścia, możesz również użyć
fileinput
modułu:Przekaż do niego pliki tak:
Przeczytaj więcej tutaj: http://docs.python.org/2/library/fileinput.html
źródło
Najprostszy sposób to zrobić
Prostym sposobem jest:
W jednym wierszu dałoby to:
Jest to jednak dość nieefektywny sposób, ponieważ przechowuje 2 wersje zawartości w pamięci (prawdopodobnie nie jest to duży problem w przypadku małych plików, ale nadal). [Dzięki Mark Amery].
Istnieją 2 łatwiejsze sposoby:
pathlib
ścieżki do pliku, której możesz użyć do innych operacji w programie:źródło
.read().splitlines()
nie jest w żaden sposób „prostsze” niż zwykłe dzwonienie.readlines()
. Po drugie, jest nieefektywna pamięci; niepotrzebnie przechowujesz dwie wersje zawartości pliku (pojedynczy ciąg zwracany przez.read()
i lista ciągów zwracanych przezsplitlines()
) jednocześnie w pamięci.Wystarczy użyć funkcji splitlines (). Oto przykład.
W wyniku pojawi się lista linii.
źródło
.readlines()
. To powoduje zapisanie dwóch kopii zawartości pliku na raz (jedna jako pojedynczy ogromny ciąg, druga jako lista linii).Jeśli chcesz mieć do czynienia z bardzo dużym / dużym plikiem i chcesz czytać szybciej (wyobraź sobie, że bierzesz udział w konkursie kodowania Topcoder / Hackerrank), możesz od razu odczytać znacznie większy fragment linii do bufora pamięci zamiast po prostu iteruj wiersz po wierszu na poziomie pliku.
źródło
process(line)
to funkcja, którą musisz wdrożyć, aby przetwarzać dane. na przykład, zamiast tej linii, jeśli ją użyjeszprint(line)
, wypisze każdą linię z bufora linii.Najłatwiejszym sposobem na to z dodatkowymi korzyściami są:
lub
lub
W takim przypadku
set
musimy pamiętać, że nie mamy zachowanej kolejności linii i pozbywamy się zduplikowanych linii.Poniżej dodałem ważny suplement z @MarkAmery :
źródło
.close
obiektu pliku ani nie używaszwith
instrukcji, w niektórych implementacjach Pythona plik może nie zostać zamknięty po odczytaniu, a proces wycieknie z otwartego uchwytu pliku. W CPython (normalnej implementacji Pythona, z której korzysta większość osób), nie stanowi to problemu, ponieważ obiekt pliku zostanie natychmiast wyrzucony do pamięci, co spowoduje zamknięcie pliku, ale ogólnie uważa się za najlepszą praktykę, aby zrobić coś takiego,with open('filename') as f: lines = list(f)
aby zapewnić, że plik zostanie zamknięty niezależnie od używanej implementacji języka Python.Użyj tego:
data
jest typem ramki danych i używa wartości, aby uzyskać ndarray. Możesz także uzyskać listę za pomocąarray.tolist()
.źródło
pandas.read_csv()
jest do odczytu danych CSV , w jaki sposób jest tutaj odpowiedni?Zarys i podsumowanie
Za pomocą a
filename
, obsługując plik zPath(filename)
obiektu lub bezpośrednio za pomocąopen(filename) as f
, wykonaj jedną z następujących czynności:list(fileinput.input(filename))
with path.open() as f
, zadzwońf.readlines()
list(f)
path.read_text().splitlines()
path.read_text().splitlines(keepends=True)
fileinput.input
lubf
ilist.append
każdą linią pojedynczof
dolist.extend
metody powiązanejf
w zrozumieniu listyPoniżej wyjaśniam przypadek użycia każdego z nich.
To doskonałe pytanie. Najpierw utwórzmy przykładowe dane:
Obiekty plików są leniwymi iteratorami, więc po prostu iteruj po nich.
Alternatywnie, jeśli masz wiele plików, użyj
fileinput.input
innego leniwego iteratora. Za pomocą tylko jednego pliku:lub w przypadku wielu plików przekaż mu listę nazw plików:
Ponownie,
f
ifileinput.input
powyżej oba są / return leniwymi iteratorami. Możesz użyć iteratora tylko jeden raz, więc aby dostarczyć funkcjonalny kod, unikając gadatliwości, użyję nieco bardziej zwięzłegofileinput.input(filename)
skąd apropos stąd.Ach, ale z jakiegoś powodu chcesz go na liście? Unikałbym tego, jeśli to możliwe. Ale jeśli nalegasz ... po prostu przekazać wynik
fileinput.input(filename)
dolist
:Inną bezpośrednią odpowiedzią jest wywołanie
f.readlines
, które zwraca zawartość pliku (do opcjonalnejhint
liczby znaków, aby w ten sposób podzielić je na wiele list).Możesz dostać się do tego obiektu pliku na dwa sposoby. Jednym ze sposobów jest przekazanie nazwy pliku do
open
wbudowanego:lub używając nowego obiektu Path z
pathlib
modułu (który bardzo mi się spodobał i z którego będę korzystać odtąd):list
zajmie się również iteratorem plików i zwróci listę - całkiem bezpośrednią metodę:Jeśli nie masz nic przeciwko odczytaniu całego tekstu do pamięci jako pojedynczego łańcucha przed podzieleniem go, możesz to zrobić jako jedno-liniowy z
Path
obiektem isplitlines()
metodą łańcuchową. Domyślniesplitlines
usuwa nowe linie:Jeśli chcesz zachować nowe linie, podaj
keepends=True
:Teraz jest to trochę głupie, aby o to poprosić, biorąc pod uwagę, że z łatwością pokazaliśmy efekt końcowy za pomocą kilku metod. Ale podczas tworzenia listy może być konieczne filtrowanie linii lub operowanie nimi, więc załóżmy tę prośbę.
Użycie
list.append
umożliwiłoby filtrowanie lub obsługę każdej linii przed jej dodaniem:Korzystanie
list.extend
byłoby nieco bardziej bezpośrednie i być może przydatne, jeśli masz wcześniej istniejącą listę:Lub bardziej idiomatycznie, zamiast tego moglibyśmy użyć zrozumienia listy, a także mapować i filtrować w nim, jeśli to pożądane:
Lub nawet bardziej bezpośrednio, aby zamknąć okrąg, po prostu przekaż go do listy, aby utworzyć nową listę bezpośrednio, bez operowania na liniach:
Wniosek
Widziałeś wiele sposobów umieszczania wierszy z pliku na liście, ale zalecam unikanie materializacji dużych ilości danych na listę i zamiast tego, jeśli to możliwe, używaj leniwej iteracji Pythona do przetwarzania danych.
To znaczy, wolę
fileinput.input
lubwith path.open() as f
.źródło
W przypadku, gdy w dokumencie są również puste wiersze, lubię czytać zawartość i przepuszczać ją,
filter
aby zapobiec pustym elementom łańcuchaźródło
Możesz także użyć polecenia loadtxt w NumPy. To sprawdza mniej warunków niż genfromtxt, więc może być szybsze.
źródło
Lubię używać następujących. Natychmiastowe czytanie linii.
Lub używając rozumienia listy:
źródło
readlines()
, co powoduje nawet karę pamięci. Możesz go po prostu usunąć, ponieważ iteracja po pliku (tekstowym) daje kolejno każdą linię.with
instrukcji do otwarcia (i niejawnego zamknięcia) pliku.Wypróbowałbym jedną z poniższych metod. Przykładowy plik, którego używam, ma nazwę
dummy.txt
. Plik można znaleźć tutaj . Zakładam, że plik znajduje się w tym samym katalogu co kod (możesz zmienić,fpath
aby podać prawidłową nazwę pliku i ścieżkę folderu).W obu poniższych przykładach podana jest lista, której szukasz
lst
.1.> Pierwsza metoda :
2.> W drugiej metodzie można użyć modułu csv.reader z biblioteki standardowej Python :
Możesz użyć jednej z dwóch metod. Czas potrzebny na stworzenie
lst
jest prawie równy w obu metodach.źródło
delimiter=' '
argument?Oto klasa
bibliotekipomocniczej Python (3) , której używam do uproszczenia operacji we / wy pliku:Następnie użyłbyś
FileIO.lines
funkcji w następujący sposób:Pamiętaj, że parametry
mode
("r"
domyślnie) ifilter_fn
( domyślnie sprawdza puste linie) są opcjonalne.Można nawet usunąć
read
,write
orazdelete
metody i po prostu pozostawićFileIO.lines
, a nawet przekształcić go w osobnej metody zwanejread_lines
.źródło
lines = FileIO.lines(path)
naprawdę jest wystarczająco prostsze niżwith open(path) as f: lines = f.readlines()
uzasadnienie istnienia tego pomocnika? Oszczędzasz 17 znaków na połączenie. (I przez większość czasu, ze względu na wydajność i pamięć, będziesz chciał zapętlić obiekt pliku bezpośrednio zamiast wczytywać jego linie do listy, więc nie będziesz nawet chciał tego często używać!) często jest fanem tworzenia małych funkcji narzędziowych, ale ten wydaje mi się, że po prostu niepotrzebnie tworzy nowy sposób pisania czegoś, co już jest krótkie i łatwe dzięki standardowej bibliotece.Wersja wiersza poleceń
Biegnij z:
źródło