So lesen Sie mit Python eine Textdatei in eine Liste oder ein Array


175

Ich versuche, die Zeilen einer Textdatei in eine Liste oder ein Array in Python einzulesen. Ich muss nur in der Lage sein, einzeln auf jedes Element in der Liste oder im Array zuzugreifen, nachdem es erstellt wurde.

Die Textdatei ist wie folgt formatiert:

0,0,200,0,53,1,0,255,...,0.

Wo ...oben ist, enthält die eigentliche Textdatei Hunderte oder Tausende weiterer Elemente.

Ich verwende den folgenden Code, um zu versuchen, die Datei in eine Liste einzulesen:

text_file = open("filename.dat", "r")
lines = text_file.readlines()
print lines
print len(lines)
text_file.close()

Die Ausgabe, die ich bekomme, ist:

['0,0,200,0,53,1,0,255,...,0.']
1

Anscheinend liest es die gesamte Datei in eine Liste von nur einem Element und nicht in eine Liste einzelner Elemente. Was mache ich falsch?


1
Nur als Notiz. Es sieht so aus, als ob diese Frage so umformuliert werden sollte, wie eine CSV-Datei in eine Liste in Python eingelesen wird. Aber ich verlasse mich auf die ursprünglichen Absichten des OP vor über 4 Jahren, die ich nicht kenne.
Demongolem



1
Bei der obersten Antwort handelt es sich um ein Duplikat von stackoverflow.com/questions/3277503/… .
AMC

Antworten:


135

Sie müssen Ihre Zeichenfolge mit in eine Liste von Werten aufteilen split()

So,

lines = text_file.read().split(',')

1
Ich denke , dass diese Antwort übertroffen werden könnte ... Wenn Sie ein mehrzeiliges betrachten .csvDatei (wie durch die OP erwähnt), beispielsweise eine Datei mit den Buchstaben 3 für Zeile , die ( a,b,c, d,e,fusw.) und das Verfahren anwenden wie oben beschrieben , was man bekommt ist eine Liste wie diese: ['a', 'b', 'c\nd', 'e', ... ](beachten Sie den Punkt 'c\nd'). Ich möchte hinzufügen, dass diese Prozedur, das obige Problem nicht zu übersehen, Daten aus einzelnen Zeilen in einer einzigen Mega-Liste zusammenfasst, normalerweise nicht das, was ich bei der Verarbeitung einer aufsatzorientierten Datendatei möchte.
Gboffi

Split wird die Zeilenumbrüche verlassen. Tun Sie dies nicht, verwenden Sie ein csvModul oder einen anderen vorhandenen Parser
Jean-François Fabre

42

Sie können auch numpy loadtxt like verwenden

from numpy import loadtxt
lines = loadtxt("filename.dat", comments="#", delimiter=",", unpack=False)

1
Ich brauche das auch. Bei einem Raspberry Pi ist mir aufgefallen, dass Numpy sehr langsam arbeitet. Für diese Anwendung habe ich eine Datei geöffnet und sie Zeile für Zeile gelesen.
Guus

2
Dies ist auch nützlich, um das Format über dtype : data-typeParameter anzugeben . docs.scipy.org/doc/numpy/reference/generated/numpy.loadtxt.html Pandas read_csv ist sehr einfach zu bedienen. Aber ich habe keine Möglichkeit gesehen, das Format dafür anzugeben. Es wurden Floats aus meiner Datei gelesen, während ich einen String brauchte. Danke @Thiru für das Anzeigen von loadtxt.
Ozgur Ozturk

1
Wenn txt-Dateien Zeichenfolgen enthalten, sollte dtype angegeben werden, also sollte es wie lines = loadtxt ("filename.dat", dtype = str, comment = "#", delimiter = ",", unpack = False) sein
Alex M981

19

Sie möchten also eine Liste von Listen erstellen ... Wir müssen mit einer leeren Liste beginnen

list_of_lists = []

Als nächstes lesen wir den Dateiinhalt Zeile für Zeile

with open('data') as f:
    for line in f:
        inner_list = [elt.strip() for elt in line.split(',')]
        # in alternative, if you need to use the file content as numbers
        # inner_list = [int(elt.strip()) for elt in line.split(',')]
        list_of_lists.append(inner_list)

Ein häufiger Anwendungsfall sind Säulendaten. Unsere Speichereinheiten sind jedoch die Zeilen der Datei, die wir einzeln gelesen haben. Daher möchten Sie möglicherweise Ihre Listenliste transponieren . Dies kann mit der folgenden Redewendung erfolgen

by_cols = zip(*list_of_lists)

Eine andere häufige Verwendung besteht darin, jeder Spalte einen Namen zu geben

col_names = ('apples sold', 'pears sold', 'apples revenue', 'pears revenue')
by_names = {}
for i, col_name in enumerate(col_names):
    by_names[col_name] = by_cols[i]

Damit können Sie homogene Datenelemente bearbeiten

 mean_apple_prices = [money/fruits for money, fruits in
                     zip(by_names['apples revenue'], by_names['apples_sold'])]

Das meiste, was ich geschrieben habe, kann mit dem csvModul aus der Standardbibliothek beschleunigt werden . Ein weiteres Modul von Drittanbietern pandasermöglicht die Automatisierung der meisten Aspekte einer typischen Datenanalyse (weist jedoch eine Reihe von Abhängigkeiten auf).


Update Während in Python 2 zip(*list_of_lists)kehrt eine andere (umgesetzt) Liste von Listen, in Python 3 hat sich die Situation geändert und zip(*list_of_lists)kehrt ein Zip - Objekt , das nicht subscriptable ist.

Wenn Sie einen indizierten Zugriff benötigen , können Sie verwenden

by_cols = list(zip(*list_of_lists))

Das gibt Ihnen eine Liste von Listen in beiden Versionen von Python.

Wenn Sie jedoch keinen indizierten Zugriff benötigen und nur ein Wörterbuch erstellen möchten, das durch Spaltennamen indiziert ist, ist ein Zip-Objekt in Ordnung ...

file = open('some_data.csv')
names = get_names(next(file))
columns = zip(*((x.strip() for x in line.split(',')) for line in file)))
d = {}
for name, column in zip(names, columns): d[name] = column

Das OP sagte, sie wollten eine Liste von Daten aus einer CSV, keine "Liste von Listen". Verwenden Sie einfach das csvModul ...
Blairg23

4

In dieser Frage wird gefragt, wie der durch Kommas getrennte Wertinhalt aus einer Datei in eine iterierbare Liste eingelesen werden kann:

0,0,200,0,53,1,0,255,...,0.

Der einfachste Weg, dies zu tun, ist mit dem csvModul wie folgt:

import csv
with open('filename.dat', newline='') as csvfile:
    spamreader = csv.reader(csvfile, delimiter=',')

Jetzt können Sie einfach spamreaderwie folgt iterieren :

for row in spamreader:
    print(', '.join(row))

Weitere Beispiele finden Sie in der Dokumentation .

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.