Ich versuche, Python zu einer Lesezeile aus einer TXT-Datei zu bringen und die Elemente der ersten Zeile in eine Liste zu schreiben. Die Elemente in der Datei waren durch Tabulatoren getrennt, daher habe ich split("\t")
die Elemente getrennt. Da die TXT-Datei viele Elemente enthält, habe ich die in jeder Zeile gefundenen Daten in einer separaten Liste gespeichert.
Das Problem, das ich derzeit habe, ist, dass es jede Liste wie folgt anzeigt:
['Name1', '7.3', '6.9', '6.6', '6.6', '6.1', '6.4', '7.3\n']
Wie kann ich \n
aus dem letzten Element der Liste entfernen und es gerecht machen '7.3'
?
Antworten:
Wenn Sie
\n
nur aus dem letzten Element entfernen möchten , verwenden Sie Folgendes:t[-1] = t[-1].strip()
Wenn Sie
\n
alle Elemente entfernen möchten , verwenden Sie Folgendes:t = map(lambda s: s.strip(), t)
Sie können auch entfernen,
\n
bevor Sie die Linie teilen:line = line.strip() # split line...
quelle
[s.strip() for s in t]
. Ich habe es zeitlich festgelegt und es ist 5,33 ms zu verarbeiten["s\n"]*10000
gegenüber 9,73 ms fürmap
.map
wird gewinnen, wenn es ein eingebautes abbildet.line = line.strip()
entfernt ALL TRAILING WHITESPACE. Das ist Metzgerei. Lesen Sie die Antwort von Jim Dennis.line.strip()
wäre es vernünftiger alsline.rstrip('\n')
und deshalb habe ich es ohne weitere Erklärung geschrieben. In diesem Fall (durch Tabulatoren getrennte Werte) haben Sie jedoch 100% Recht: Man sollte in der Tat vorsichtig sein, wenn führende und nachfolgende Leerzeichen entfernt werden, da eine leere erste oder letzte Spalte möglicherweise "verschwindet".Ab Python3
map
gibt nicht mehr a zurück,list
sondern amapObject
, daher sieht die Antwort ungefähr so aus>>> map(lambda x:x.strip(),l) <map object at 0x7f00b1839fd0>
Sie können mehr darüber auf lesen Was ist neu in Python 3.0 .
Wie kann man nun durchkommen?
Fall 1 - Der
list
Anrufmap
mit alambda
map
Gibt einen Iterator zurück .list
ist eine Funktion, die einen Iterator in eine Liste konvertieren kann. Daher müssen Sie einenlist
Anruf abschließenmap
. Die Antwort lautet nun:>>> l = ['Name1', '7.3', '6.9', '6.6', '6.6', '6.1', '6.4', '7.3\n'] >>> list(map(lambda x:x.strip(),l)) ['Name1', '7.3', '6.9', '6.6', '6.6', '6.1', '6.4', '7.3']
Sehr gut, wir bekommen die Ausgabe. Jetzt überprüfen wir, wie lange es dauert, bis dieser Code ausgeführt wird.
$ python3 -m timeit "l = ['Name1', '7.3', '6.9', '6.6', '6.6', '6.1', '6.4', '7.3\n'];list(map(lambda x:x.strip(),l))" 100000 loops, best of 3: 2.22 usec per loop
2,22 Mikrosekunden. Das ist nicht so schlimm Aber gibt es effizientere Wege?
Fall 2 - Der
list
Anrufmap
ohne alambda
lambda
wird von vielen in der Python-Community (einschließlich Guido ) missbilligt . Abgesehen davon wird die Geschwindigkeit des Programms erheblich reduziert. Daher müssen wir dies so weit wie möglich vermeiden. Die Toplevel-Funktionstr.strip
. Kommt uns hier zu Hilfe.Das
map
kann ohne Verwendunglambda
vonstr.strip
as neu geschrieben werden>>> list(map(str.strip,l)) ['Name1', '7.3', '6.9', '6.6', '6.6', '6.1', '6.4', '7.3']
Und jetzt zu den Zeiten.
$ python3 -m timeit "l = ['Name1', '7.3', '6.9', '6.6', '6.6', '6.1', '6.4', '7.3\n'];list(map(str.strip,l))" 1000000 loops, best of 3: 1.38 usec per loop
Fantastisch. Sie können die Effizienzunterschiede zwischen den beiden Möglichkeiten erkennen. Es ist fast 60% schneller. Daher ist der Ansatz ohne Verwendung von a
lambda
hier eine bessere Wahl.Fall 3 - Befolgen Sie die Richtlinien, den regulären Weg
Ein weiterer wichtiger Punkt von Was ist neu in Python 3.0? Es wird empfohlen, dies nach Möglichkeit zu vermeiden
map
.So können wir dieses Problem ohne
map
eine regulärefor
Schleife lösen .Die triviale Art der Lösung (die Brute-Force) wäre:
>>> l = ['Name1', '7.3', '6.9', '6.6', '6.6', '6.1', '6.4', '7.3\n'] >>> final_list = [] >>> for i in l: ... final_list.append(i.strip()) ... >>> final_list ['Name1', '7.3', '6.9', '6.6', '6.6', '6.1', '6.4', '7.3']
Das Timing-Setup
def f(): l = ['Name1', '7.3', '6.9', '6.6', '6.6', '6.1', '6.4', '7.3\n'] final_list = [] for i in l: final_list.append(i.strip()) import timeit print(min(timeit.repeat("f()","from __main__ import f")))
Und das Ergebnis.
1.5322505849981098
Wie Sie sehen, ist die Brute-Force hier etwas langsamer. Für einen normalen Programmierer ist es jedoch definitiv besser lesbar als eine
map
Klausel.Fall 4 - Listenverständnisse
Ein Listenverständnis ist hier ebenfalls möglich und entspricht dem in Python2.
>>> [i.strip() for i in l] ['Name1', '7.3', '6.9', '6.6', '6.6', '6.1', '6.4', '7.3']
Nun zu den Timings:
$ python3 -m timeit "l = ['Name1', '7.3', '6.9', '6.6', '6.6', '6.1', '6.4', '7.3\n'];[i.strip() for i in l]" 1000000 loops, best of 3: 1.28 usec per loop
Wie Sie sehen, ist das Listenverständnis effektiver als
map
(auch das ohne alambda
). Daher lautet die Daumenregel in Python3, stattdessen ein Listenverständnis zu verwendenmap
Fall 5 - In-Place-Mechanismen und Raumeffizienz ( TMT )
Eine letzte Möglichkeit besteht darin, die Änderungen in der Liste selbst vorzunehmen. Dies spart viel Speicherplatz. Dies kann mit erfolgen
enumerate
.>>> l = ['Name1', '7.3', '6.9', '6.6', '6.6', '6.1', '6.4', '7.3\n'] >>> for i,s in enumerate(l): ... l[i] = s.strip() ... >>> l ['Name1', '7.3', '6.9', '6.6', '6.6', '6.1', '6.4', '7.3']
Das Timing-Ergebnis wäre
1.4806894720022683
. Dieser Weg ist jedoch platzsparend.Fazit
Eine vergleichende Liste von Timings (sowohl Python 3.4.3 als auch Python 3.5.0)
---------------------------------------------------- |Case| method | Py3.4 |Place| Py3.5 |Place| |----|-----------------|-------|-----|-------|-----| | 1 | map with lambda | 2.22u | 5 | 2.85u | 5 | | 2 | map w/o lambda | 1.38u | 2 | 2.00u | 2 | | 3 | brute-force | 1.53u | 4 | 2.22u | 4 | | 4 | list comp | 1.28u | 1 | 1.25u | 1 | | 5 | in-place | 1.48u | 3 | 2.14u | 3 | ----------------------------------------------------
Beachten Sie schließlich, dass das Listenverständnis der beste und die
map
Verwendunglambda
der schlechteste ist. Aber nochmal --- NUR IN PYTHON3quelle
Es hört sich so an, als ob Sie so etwas wie die Perl-
chomp()
Funktion wollen.Das ist in Python trivial:
def chomp(s): return s[:-1] if s.endswith('\n') else s
... vorausgesetzt, Sie verwenden Python 2.6 oder höher. Ansonsten benutze einfach das etwas ausführlichere:
def chomp(s): if s.endwith('\n'): return s[:-1] else: return s
Wenn Sie alle neuen Zeilen vom Ende einer Zeichenfolge entfernen möchten (in dem ungeraden Fall, in dem aus irgendeinem Grund mehrere nachfolgende Zeilenumbrüche vorhanden sein können):
def chomps(s): return s.rstrip('\n')
Offensichtlich sollten Sie niemals eine solche Zeichenfolge sehen, die von normalen Python-Dateiobjekten
readline()
oderreadlines()
Methoden zurückgegeben wird.Ich habe gesehen, wie Leute blind die letzten Zeichen (mit
s[:-1]
Slicing) aus den Ergebnissen von Dateienreadline()
und ähnlichen Funktionen entfernt haben. Dies ist eine schlechte Idee, da dies zu einem Fehler in der letzten Zeile der Datei führen kann (falls eine Datei mit etwas anderem als einer neuen Zeile endet).Zuerst könnten Sie in ein falsches Sicherheitsgefühl versetzt werden, wenn Sie die letzten Zeichen blind von den Zeilen entfernen, die Sie gelesen haben. Wenn Sie zum Erstellen Ihrer Testsuite-Dateien einen normalen Texteditor verwenden, wird von den meisten stillschweigend eine neue Zeile am Ende der letzten Zeile hinzugefügt. Um eine gültige Testdatei zu erstellen, verwenden Sie folgenden Code:
f = open('sometest.txt', 'w') f.write('some text') f.close()
... und wenn Sie diese Datei erneut öffnen und die Methoden
readline()
oderreadlines()
file verwenden, werden Sie feststellen, dass der Text ohne den nachfolgenden Zeilenumbruch gelesen wird.Dieses Versäumnis, Textdateien zu berücksichtigen, die auf Zeichen ohne Zeilenumbruch enden, hat viele UNIX-Dienstprogramme und Skriptsprachen seit vielen Jahren geplagt. Es ist ein dummer Eckfehler, der sich gerade oft genug in den Code einschleicht, um ein Schädling zu sein, aber nicht oft genug, damit die Leute daraus lernen können. Wir könnten argumentieren, dass "Text" -Dateien ohne den ultimativen Zeilenumbruch "beschädigt" oder nicht standardisiert sind. und das kann für einige Programmierspezifikationen gültig sein.
Es ist jedoch allzu einfach, Eckfälle in unserer Codierung zu ignorieren und diese Unwissenheit Menschen zu beißen, die später von Ihrem Code abhängig sind. Wie meine Frau sagt: Wenn es um Programmierung geht ... üben Sie sicheres Hex!
quelle
line = line.rstrip('\n')
sollten Sie vor dem Parsen der Zeile in Felder überprüfen, ob eine neue Zeile vorhanden ist (oder diese blind entfernen, wenn sie vorhanden ist ).Listenverständnis verwenden:
myList = ['Name1', '7.3', '6.9', '6.6', '6.6', '6.1', '6.4', '7.3\n'] [(el.strip()) for el in myList]
quelle
von diesem Link :
Sie können die Methode rstrip () verwenden. Beispiel
mystring = "hello\n" print(mystring.rstrip('\n'))
quelle
Als alternative Methode können Sie split () verwenden (ohne Argumente), wenn Sie wissen, dass Ihre Daten keine Leerzeichen enthalten, was anscheinend der Fall ist. Dies teilt sich auf Leerzeichen auf und verwendet einen effizienteren Algorithmus als die andere Version von Split. Außerdem werden an beiden Enden Leerzeichen entfernt.
Und das ist es.
quelle
Du könntest es tun -
DELIMITER = '\t' lines = list() for line in open('file.txt'): lines.append(line.strip().split(DELIMITER))
Das
lines
hat den gesamten Inhalt Ihrer Datei.Man könnte auch Listenverständnisse verwenden, um dies kompakter zu machen.
lines = [ line.strip().split(DELIMITER) for line in open('file.txt')]
quelle
Dies wird auch funktionieren,
f=open('in.txt','r') for line in f: parline = line[:-1].split(',')
quelle
str.strip () entfernt die Leerzeichen. Sie können auch benutzerdefinierte Zeichen als Argument an Strip übergeben. Die Strip- Funktion entfernt die Leerzeichen / benutzerdefinierten Zeichen an beiden Enden der Zeichenfolge. lstrip () und rstrip () sind Funktionen für den linken bzw. rechten Streifen.
Z.B:
test_str = "Vishaka\n" test_str = test_str.strip()
test_str ist jetzt Vishaka
quelle
Sie greifen auf das letzte Element der Menge zu und speichern den Wert in einer Variablen.
Also hast du:
fileName = '7.3\n'
dann mach einfach:
was dich mit verlassen wird
7.3
. Speichern Sie diesen Wert dann wieder im letzten Element der Menge.Sie können nur die linke oder rechte Seite verwenden
lstrip()
oderrstrip()
entfernen.quelle
Da es bei der Frage des OP darum geht, das Zeilenumbruchzeichen vom letzten Element zu entfernen, würde ich es zurücksetzen mit
the_list[-1].rstrip()
:>>> the_list = ['Name1', '7.3', '6.9', '6.6', '6.6', '6.1', '6.4', '7.3\n'] >>> the_list[-1] = ls[-1].rstrip() >>> the_list ['Name1', '7.3', '6.9', '6.6', '6.6', '6.1', '6.4', '7.3']
Es ist O (1).
quelle
Dies funktioniert, um die
\n
(neue Zeile) von einem Element in einer Liste zu entfernen, wobei nur das erste Element in der Zeichenfolge entfernt wirddef remove_end(s): templist=[] for i in s: templist.append(i) return(templist[0])
quelle
Ich hatte dieses Problem und löste es mit der oben beschriebenen Chomp-Funktion:
def chomp(s): return s[:-1] if s.endswith('\n') else s def trim_newlines(slist): for i in range(len(slist)): slist[i] = chomp(slist[i]) return slist ..... names = theFile.readlines() names = trim_newlines(names) ....
quelle
\r\n
Verwenden Sie Splitlines , um mit vielen Zeilenumbruchbegrenzern umzugehen, einschließlich Zeichenkombinationen wie . Kombinieren Sie kommen und Teilungslinien entfernen / ersetzen Sie alle Zeilenumbrüche aus einem Strings
:''.join(s.splitlines())
So entfernen Sie genau einen nachlauf Newline, übergibt
True
alskeepends
Argument , um die Trennzeichen beibehalten, das Entfernen nur die Trennzeichen in der letzten Zeile:def chomp(s): if len(s): lines = s.splitlines(True) last = lines.pop() return ''.join(lines + last.splitlines()) else: return ''
quelle
new_list = ['Name1', '7.3', '6.9', '6.6', '6.6', '6.1', '6.4', '7.3\n'] for i in range(len(new_list)): new_list[i]=new_list[i].replace('\n','') print(new_list)
Die Ausgabe wird so sein
['Name1', '7.3', '6.9', '6.6', '6.6', '6.1', '6.4', '7.3']
quelle