Zeilenumbruch aus String in einer Liste entfernen.

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
Antworten
ruiin
User
Beiträge: 20
Registriert: Mittwoch 11. April 2012, 16:31
Wohnort: Essen

Hi,

hab im Internet und über die Suchfunktion keine für mich funktionierende Entsprechung gefunden.

Ich möchte aus einem String in einer Liste den Zeilenumbruch raus holen, ambesten ohne das ein Leerzeichen entsteht.
Mein bisheriger Ansatz:

Code: Alles auswählen

		for i in filelines:
			if "\n" in i:
				i = i.replace("\n", " ")
Das bei funktionier die replace-Methode nicht so, das sein Ergebnis das Listenelement überschreibt. Auch muss ich mit dieser Methode ein Leerzeichen einfügen, da ein Leerstring nicht möglich ist.

Wenn jemand einen anderen Ansatz hat, immer her damit :)
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Strings sind in Python immutable, d.h. Du kannst sie nicht ändern. Jede Operation auf einem String erzeugt ein *neues* String-Objekt. Insofern machst Du das schon richtig, dass Du das `i` überschreibst.

Die "Liste" wird natürlich nicht aktualisiert - das Objekt hinter `i` weiß ja gar nicht, dass es aus einer Liste stammt ;-) Wenn, musst Du schon den Index kennen und den Eintrag der Liste an dieser Stelle überschreiben. Einen solchen Index liefert Dir die `enumerate`-Funktion. (Achtung: Ggf. ist Deine vermeintliche Liste gar keine und Du kannst dort nicht einfach etwas überschreiben - der Name `filelines` legt das nahe; sofern es sich um ein File-Object handelt)

In Python geht man aber meist eher so vor, dass Du eine *neue* Liste erzeugst, welche Du entsprechend mit korrigierten Elementen aufbaust.

Der Name `filelines` legt nahe, dass diese Zeilen aus einer Textdatei stammen. Dann kannst Du *direkt* über ein file-Objekt iterieren und die Zeilen behandeln:

Code: Alles auswählen

with open(filename) as infile:
    lines = [line.strip() for line in infile]
`strip` entfernt Whitespaces am Ende eines Strings - reicht Dir das?

Je nach dem, was Du mit den Zeilen vor hast, musst Du diese auch nicht unbedingt in eine Liste packen, sondern könntest sie auch direkt weiterverarbeiten... aber dafür wissen wir nicht genug über Deinen Anwendungsfall ;-)
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
Benutzeravatar
cofi
Python-Forum Veteran
Beiträge: 4432
Registriert: Sonntag 30. März 2008, 04:16
Wohnort: RGFybXN0YWR0

Das Problem ist, dass du den lokalen Namen neu bindest, nicht die Liste veraenderst.

Und ein leerer String ist bei `str.replace` sehr wohl moeglich:

Code: Alles auswählen

In [1]: s = """Let there be
   ...: some
   ...: newlines
   ...: """

In [2]: s.replace('\n', '')
Out[2]: 'Let there besomenewlines'

Code: Alles auswählen

lines[:] = [line.replace('\n', '') for line in lines]
oder in lang:

Code: Alles auswählen

for i, line in enumerate(lines):
    lines[i] = line.replace('\n', '')
ruiin
User
Beiträge: 20
Registriert: Mittwoch 11. April 2012, 16:31
Wohnort: Essen

danke Hyperion.

Hat so super funktioniert. Der Code macht nicht nur Whitespaces weg sondern auch Maskierungen wie "\n".

Muss mir in meinen Büchern nochmal das Kaptel durchlesen, diese Operation betreffend.
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Unter Deinen Büchern ist nicht zufälliger Weise das OpenBook von Galileo? Wenn ja, solltest Du dieses Buch vergessen; gibt dazu einige Threads und Kommentare im Forum.

Du solltest vor allem die Dokumentation von Python konsultieren; diese ist im Zweifel viel ergiebiger und aktueller als ein Buch. Bücher sind ja eher selten Referenz, sondern eher Tutorial.
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
ruiin
User
Beiträge: 20
Registriert: Mittwoch 11. April 2012, 16:31
Wohnort: Essen

hab mal mit dem von O'relley angefangen und momentan blättere ich in nem wälzer von mitp, ist zwar sehr detailliert, kommt aber an das O'relley nicht dran.
Benutzeravatar
Matflasch
User
Beiträge: 41
Registriert: Donnerstag 25. März 2004, 15:42
Wohnort: Hamburg
Kontaktdaten:

Code: Alles auswählen

In [1]: l = ['\n\nhello\n', '\nworld\n\n', 'example\n', '!\n\n\n']

In [2]: ''.join(l)
Out[2]: '\n\nhello\n\nworld\n\nexample\n!\n\n\n'

In [3]: ' '.join(l)
Out[3]: '\n\nhello\n \nworld\n\n example\n !\n\n\n'

In [4]: ''.join(map(str.strip, l))
Out[4]: 'helloworldexample!'

In [5]: ' '.join(map(str.strip, l))
Out[5]: 'hello world example !'
so geht es auch ;)
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Matflasch hat geschrieben:

Code: Alles auswählen

l = ['\n\nhello\n', '\nworld\n\n', 'example\n', '!\n\n\n']
print(''.join(l))
print(' '.join(map(str.strip, l))) 
so geht es auch ;)
Durch die Brust ins Auge...

Code: Alles auswählen

# wie ich oben schon beinahe schrieb:
''.join(item.strip() for item in lines)
# oder analog zu Dir
# ACHTUNG: Das ist eine deprecated string function... ab 3.x funzt der Code nicht mehr!
''.join(map(string.strip, lines))
Dein erstes `join` konterkariert ja geradezu den Einsatz von `map` ;-)

Und wie schon im Code steht: Das ist eine deprecated String function. Insofern bietet sich der Einsatz nicht an!
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
Benutzeravatar
Matflasch
User
Beiträge: 41
Registriert: Donnerstag 25. März 2004, 15:42
Wohnort: Hamburg
Kontaktdaten:

Danke! Das hatte ich nicht bedacht, dann eben so ;)

Code: Alles auswählen

In [8]: ' '.join(map(lambda s: s.replace('\n', ''), l))
Out[8]: 'hello world example !'
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Hm... ich bin ja ein Freund von `map`, aber wenn ich mir erst eine lambda-Funktion bauen muss, um es nutzen zu können, ist es imho meist der falsche Ansatz ;-)
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
jerch
User
Beiträge: 1669
Registriert: Mittwoch 4. März 2009, 14:19

Hyperion hat geschrieben:Hm... ich bin ja ein Freund von `map`, aber wenn ich mir erst eine lambda-Funktion bauen muss, um es nutzen zu können, ist es imho meist der falsche Ansatz ;-)
Na dann halt ohne map :twisted: :

Code: Alles auswählen

>>> l = ['\n\nhello\n', '\nworld\n\n', 'example\n', '!\n\n\n']
>>> f = lambda l: ' '.join((l[0].strip(), f(l[1:]))) if l[1:] else l[0].strip()
>>> f(l)
'hello world example !'
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

Hyperion hat geschrieben:Und wie schon im Code steht: Das ist eine deprecated String function. Insofern bietet sich der Einsatz nicht an!
Ach, da geht noch was:

Code: Alles auswählen

# ihr ahnt schon wohin das geht
from operator import methodcaller
l = ['\n\nhello\n', '\nworld\n\n', 'example\n', '!\n\n\n']
# wer braucht schon lambda wenn wir uns unser eigenes lambda basteln können
replace = methodcaller("replace", "\n", "")
# et voila
print " ".join(map(replace, l))
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
ruiin
User
Beiträge: 20
Registriert: Mittwoch 11. April 2012, 16:31
Wohnort: Essen

ich glaub hyperions vorschlag ist ganz klar der einfachste hier. :o
Benutzeravatar
Matflasch
User
Beiträge: 41
Registriert: Donnerstag 25. März 2004, 15:42
Wohnort: Hamburg
Kontaktdaten:

Hyperion hat geschrieben:Und wie schon im Code steht: Das ist eine deprecated String function. Insofern bietet sich der Einsatz nicht an!
hatte es wohl nur überflogen :roll:
string.strip ist deprecated, str.strip ist aber ja der 'Ersatz' und funktioniert. :D

Code: Alles auswählen

#!/usr/bin/env python3.2
l = ['\n\nhello\n', '\nworld\n\n', 'example\n', '!\n\n\n']
print(''.join(map(str.strip, l)))
print(' '.join(map(str.strip, l)))
print(type(str), str)

Code: Alles auswählen

% python3.2 test.py
helloworldexample!
hello world example !
<class 'type'> <class 'str'>
BlackJack

@Matflasch: Man verliert dadurch natürlich die Polymorphie weil `str.strip()` nur bei `str`-Exemplaren funktioniert:

Code: Alles auswählen

In [1296]: str.strip(bytearray())
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)

/home/bj/<ipython console> in <module>()

TypeError: descriptor 'strip' requires a 'str' object but received a 'bytearray'

In [1297]: str.strip(u'')
---------------------------------------------------------------------------
TypeError                                 Traceback (most recent call last)

/home/bj/<ipython console> in <module>()

TypeError: descriptor 'strip' requires a 'str' object but received a 'unicode'
Sowohl `bytearray` als auch `unicode` haben aber eine `strip()`-Methode.
Antworten