Seite 1 von 1

Zeilenumbruch aus String in einer Liste entfernen.

Verfasst: Dienstag 22. Mai 2012, 16:22
von ruiin
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 :)

Re: Zeilenumbruch aus String in einer Liste entfernen.

Verfasst: Dienstag 22. Mai 2012, 16:36
von Hyperion
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 ;-)

Re: Zeilenumbruch aus String in einer Liste entfernen.

Verfasst: Dienstag 22. Mai 2012, 16:36
von cofi
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', '')

Re: Zeilenumbruch aus String in einer Liste entfernen.

Verfasst: Dienstag 22. Mai 2012, 16:47
von ruiin
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.

Re: Zeilenumbruch aus String in einer Liste entfernen.

Verfasst: Dienstag 22. Mai 2012, 16:52
von Hyperion
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.

Re: Zeilenumbruch aus String in einer Liste entfernen.

Verfasst: Dienstag 22. Mai 2012, 18:00
von ruiin
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.

Re: Zeilenumbruch aus String in einer Liste entfernen.

Verfasst: Dienstag 22. Mai 2012, 20:03
von Matflasch

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 ;)

Re: Zeilenumbruch aus String in einer Liste entfernen.

Verfasst: Dienstag 22. Mai 2012, 20:09
von Hyperion
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!

Re: Zeilenumbruch aus String in einer Liste entfernen.

Verfasst: Dienstag 22. Mai 2012, 20:15
von Matflasch
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 !'

Re: Zeilenumbruch aus String in einer Liste entfernen.

Verfasst: Dienstag 22. Mai 2012, 20:30
von Hyperion
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 ;-)

Re: Zeilenumbruch aus String in einer Liste entfernen.

Verfasst: Mittwoch 23. Mai 2012, 00:30
von jerch
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 !'

Re: Zeilenumbruch aus String in einer Liste entfernen.

Verfasst: Mittwoch 23. Mai 2012, 07:47
von Leonidas
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))

Re: Zeilenumbruch aus String in einer Liste entfernen.

Verfasst: Mittwoch 23. Mai 2012, 08:39
von ruiin
ich glaub hyperions vorschlag ist ganz klar der einfachste hier. :o

Re: Zeilenumbruch aus String in einer Liste entfernen.

Verfasst: Mittwoch 23. Mai 2012, 20:50
von Matflasch
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'>

Re: Zeilenumbruch aus String in einer Liste entfernen.

Verfasst: Mittwoch 23. Mai 2012, 21:12
von 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.