Pytanie W Pythonie, jak mogę czytać plik po linii na liście?


Jak odczytać każdą linię pliku w Pythonie i zapisać każdą linię jako element na liście?

Chcę czytać plik wiersz po linii i dołączać każdą linię na końcu listy.


1703
2017-07-18 22:25


pochodzenie




Odpowiedzi:


with open(fname) 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] 

1659
2017-07-18 22:28



Nie używaj file.readlines() w for-oop, sam obiekt pliku wystarczy: lines = [line.rstrip('\n') for line in file] - jfs
W przypadku, gdy używasz Big Data readlines() nie jest bardzo wydajny, ponieważ może spowodować MemoryError. W tym przypadku lepiej jest iterować plik za pomocą for line in f: i praca z każdym line zmienna. - DarkCygnus
Sprawdziłem profil pamięci na różne sposoby podane w odpowiedziach przy użyciu wspomnianej procedury tutaj. Wykorzystanie pamięci jest o wiele lepsze, gdy każda linia jest odczytywana z pliku i przetwarzana zgodnie z sugestią @DevShark tutaj. Przytrzymanie wszystkich linii w obiekcie kolekcji to nie dobry pomysł, jeśli pamięć jest ograniczeniem lub plik jest duży. Czas wykonania jest podobny w obu podejściach. - Tirtha R
Również, .rstrip() będzie działać nieco szybciej, jeśli usuniesz białe spacje z końców linii. - Gringo Suave


Widzieć Wejście i Ouput:

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

lub z usunięciem znaku nowej linii:

lines = [line.rstrip('\n') for line in open('filename')]

Komentarz edytora: To oryginalne polecenie usuwania pustych przestrzeni, line.strip(), jak sugeruje komentarz Janusa Troelsena, zniknie wszystkie wiodące i końcowe białe spacje, a nie tylko spływ \n.


781
2017-07-18 22:28



jeśli chcesz odrzucić nową linię: lines = (line.rstrip('\n') for line in open(filename)) - Janus Troelsen
Lista powinna być lines = [line.rstrip('\n') for line in open(filename)] - Lazik
Czy druga opcja nie pozostawi pliku otwartego (skoro nie jest chroniony przez kontekst)? - yo'
@yo "Tak, ale większość ludzi nie dba o to w małych programach. Nie ma żadnej szkody w małych programach, ponieważ przeciekany obiekt pliku jest zbiorem śmieci, ale nie jest to dobry nawyk. - Martin Ueding
Bezpieczniej: with open('filename') as f: lines = [line.rstrip('\n') for line in f] - becko


Jest to bardziej wyraźne niż to konieczne, ale robi to, co chcesz.

with open("file.txt", "r") as ins:
    array = []
    for line in ins:
        array.append(line)

369
2017-07-18 22:27



To jest bezpośrednia odpowiedź na to pytanie - Joop


Da to "tablicę" linii z pliku.

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

206
2017-07-18 22:27



open zwraca plik, który można powtórzyć. Gdy wykonujesz iterację po pliku, otrzymujesz linie z tego pliku. tuple może pobrać iterator i utworzyć instancję krotki dla ciebie z iteratora, który mu podasz. lines jest krotką utworzoną z linii pliku. - Noctis Skytower
@MarshallFarrier Spróbuj lines = open(filename).read().split('\n') zamiast. - Noctis Skytower
czy zamyka plik? - Vanuan
@NoctisSkytower Znajduję lines = open(filename).read().splitlines() trochę czystszy i uważam, że lepiej radzi sobie z końcówkami linii DOS. - jaynp
@ mklement0 Zakładając plik 1000 linii, a list zajmuje o 13,22% więcej miejsca niż tuple. Wyniki pochodzą z from sys import getsizeof as g; i = [None] * 1000; round((g(list(i)) / g(tuple(i)) - 1) * 100, 2). Tworząc tuple zajmuje o 4,17% więcej czasu niż tworzenie list (z odchyleniem standardowym 0,16%). Wyniki pochodzą z działania from 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 faworyzuje przestrzeń nad prędkością, gdy nie ma potrzeby zmiany właściwości. - Noctis Skytower


Jeśli chcesz \n w zestawie:

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

Jeśli nie chcesz \n w zestawie:

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

150
2018-03-02 04:22





Można po prostu wykonać następujące czynności, jak zasugerowano:

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

Zwróć uwagę, że to podejście ma 2 wady:

1) Przechowujesz wszystkie linie 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 przetwarzasz linie po tym, nie jest to wydajne (wymaga dwóch rzutów zamiast jednego).

Lepszym podejściem w przypadku ogólnym byłoby:

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

Gdzie definiujesz swoją funkcję procesu w dowolny sposób. Na przykład:

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

(Wdrażanie Superman klasa jest pozostawiona jako ćwiczenie dla ciebie).

To zadziała ładnie dla dowolnego rozmiaru pliku i przejdziesz przez plik w ciągu zaledwie 1-ego przebiegu. Zwykle działa to w przypadku parserów generycznych.


93
2018-02-25 09:13



To było dokładnie to, czego potrzebowałem - i dzięki za wyjaśnienie wad. Jako początkujący w Pythonie, świetnie jest zrozumieć, dlaczego rozwiązanie jest rozwiązaniem. Twoje zdrowie! - Ephexx
Myśl trochę bardziej Corey. Czy naprawdę chcesz, aby twój komputer czytał każdą linię, nie robiąc nic z tymi liniami? Na pewno zdasz sobie sprawę, że zawsze musisz je przetwarzać w taki czy inny sposób. - DevShark
Zawsze musisz coś zrobić z liniami. Może to być tak proste, jak drukowanie linii lub ich liczenie. Nie ma żadnej wartości, gdy twój proces odczytuje linie w pamięci, ale nic z tym nie robi. - DevShark
Zawsze musisz coś z nimi zrobić. Myślę, że chodzi o to, że chcecie zastosować funkcję do wszystkich naraz, a nie pojedynczo. Tak jest w rzeczywistości czasami. Jednak z punktu widzenia pamięci jest to bardzo nieefektywne i uniemożliwia czytanie plików, jeśli jego ślad jest większy niż ramka. Właśnie dlatego zwykle generyczne parsery działają w sposób opisany przeze mnie. - DevShark
@PierreOcinom, który jest poprawny. Biorąc pod uwagę, że plik jest otwarty w trybie tylko do odczytu, nie można zmodyfikować oryginalnego pliku za pomocą powyższego kodu. Aby otworzyć plik zarówno do odczytu, jak i zapisu, użyj open('file_path', 'r+') - DevShark


Jeśli nie interesuje cię zamykanie pliku, ten jeden liner działa:

lines = open('file.txt').read().split("\n")

The tradycyjny droga:

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

Za pomocą with (Zalecana):

with open('file.txt') as fp:
    lines = fp.read().split("\n")

61
2018-04-20 05:53



W niektórych przypadkach może być w porządku, ale to nie zamyka pliku, nawet po zakończeniu pętli - stackoverflow.com/a/1832589/232593 - Merlyn Morgan-Graham
The with blok zamyka plik automatycznie. Nie potrzeba finału fp.close() linia w tym ostatnim przykładzie. Widzieć: repl.it/IMeA/0 - Merlyn Morgan-Graham
Zawsze dbaj o zamknięcie pliku! Bądź dobrym obywatelem zasobów! - Nick


Powinno to zawierać enkapsulację polecenia open.

array = []
with open("file.txt", "r") as f:
  for line in f:
    array.append(line)

38
2017-10-28 15:40



f.readlines () robi to samo. nie trzeba dodawać do pustej listy. - Corey Goldberg
Masz rację. Zapewnia to wgląd w rozwiązanie, jeśli chcesz coś zrobić podczas czytania w liniach. Podobnie jak niektóre transformacje strip / regex. - cevaris


Dane do listy

Załóżmy, że mamy plik tekstowy z naszymi danymi, jak w następujących liniach:

Treść pliku tekstowego:

   line 1
   line 2
   line 3
  • Otwórz cmd w tym samym katalogu (kliknij prawym przyciskiem myszy i wybierz cmd lub PowerShell)
  • Biegać python i w tłumaczu napisz:

Skrypt w języku Python

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

Używanie append

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

Lub...

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

Lub...

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

36
2018-04-26 04:57



jest encoding="utf-8" wymagany? - Mausy5043
@ Mausy5043 nie, ale kiedy czytasz plik tekstowy, możesz mieć dziwną postać (szczególnie w języku włoskim) - Giovanni Gianni