Textformatierungsproblem

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
bjoernh
User
Beiträge: 20
Registriert: Donnerstag 27. Mai 2010, 15:45

Hallo Leute,
Ich habe eine Liste erstellt und in eine Datei geschrieben. In der Datei sieht das (mit notepad geöffnet) so aus:
...
hundred, freight, public, director
value, Münze
fit, logic
...

Wenn ich das aber z.B. in excel (oder hier ins Forum) reinkopiere, dann sieht es so aus:

...
hundred
, freight
, public
, director
value
, Münze
fit
...

Weiß jemand was hier los ist? Ich möchte die Formatierung oben haben.
Zuletzt geändert von bjoernh am Donnerstag 1. Juli 2010, 08:26, insgesamt 1-mal geändert.
Darii
User
Beiträge: 1177
Registriert: Donnerstag 29. November 2007, 17:02

Glaskugel sagt: Du gibst die Werte nacheinander mit print aus und Notepad kommt mit dem Zeilenumbruch nicht klar. Glaskugel sagt: Mach Komma hinter print

Code: Alles auswählen

print irgendwas,
Falls Glaskugel kaputt: *etwas* mehr Informationen dürften es schon sein…
bjoernh
User
Beiträge: 20
Registriert: Donnerstag 27. Mai 2010, 15:45

Code reinschreiben wär wohl gut gewesen, hatte gehofft, das es auch so ein bekanntes Problem ist.
Ich kreiere die Liste in etwa so:

Code: Alles auswählen

...
heisig_string = heisig_string + ", " + heisig_splittab[1]
...
exout_file.write(heisig_string)
Darii
User
Beiträge: 1177
Registriert: Donnerstag 29. November 2007, 17:02

Was erwartest du jetzt von uns? Laut deinem Code dürfte da nirgends ein Zeilenumbrucht auftauchen. Nichtmal da wo du ihn haben willst. *etwas* mehr Informationen dürften es schon sein…

PS: Vermutlich ist da noch irgendwo ein Zeilenumbruch in den Teilstrings der da nicht hingehört.
bjoernh
User
Beiträge: 20
Registriert: Donnerstag 27. Mai 2010, 15:45

Code: Alles auswählen

def to_unicode_or_bust(
        obj, encoding='utf-8'):
    if isinstance(obj, basestring):
        if not isinstance(obj, unicode):
            obj = unicode(obj, encoding)
    return obj

	
def heisig_find(vocab):			#returns heisig-keywords from first tab of "vocab"
	vocab_uni = to_unicode_or_bust(vocab)
	vocab_uni = vocab_uni.rstrip()
	vocab_split_tab_uni = vocab_uni.split("\t")
	n = len(vocab_split_tab_uni[0])
	vocab_hanzi_splitbychar = list(vocab_split_tab_uni[0])
	#print vocab_hanzi_splitbychar.encode('utf-8')
	heisig_string = ""
	for i in range(n):
		for heisig in heisig_file.readlines():
			heisig_uni = to_unicode_or_bust(heisig)
			heisig_splittab = heisig_uni.split("\t")
			heisig_list = list(heisig_splittab[0])
			index = vocab_hanzi_splitbychar[i].find(heisig_list[0])
			if index!=-1:
				heisig_splittab[1] = heisig_splittab[1].strip('\n')
				heisig_string = heisig_string + ", " + heisig_splittab[1] 
		heisig_file.seek(0)
		heisig_string = heisig_string.replace('\n', '')
		new_line = heisig_string.lstrip(', ') + '\n'
	return new_line

import codecs

MyDir = '/Programme/notepad++/Python/Test'

exout_file = codecs.open(MyDir + '/' + 'exoututf8.txt', encoding = 'utf-8-sig', mode = 'w')
newvocab_file = codecs.open(MyDir + '/' + 'nvutf8.txt', encoding = 'utf-8-sig', mode = 'r')
heisig_file = codecs.open(MyDir + '/' + 'heisig.txt', encoding = 'utf-8-sig', mode = 'r')

for line_nv in newvocab_file.readlines():
	exout_file.write(heisig_find(line_nv))

exout_file.close()
newvocab_file.close()
heisig_file.close()
Zuletzt geändert von Anonymous am Mittwoch 30. Juni 2010, 07:36, insgesamt 1-mal geändert.
Grund: Quelltext in Python-Code-Tags gesetzt.
Benutzeravatar
Hyperion
Moderator
Beiträge: 7478
Registriert: Freitag 4. August 2006, 14:56
Wohnort: Hamburg
Kontaktdaten:

Kann man denn innerhalb von 4 Stunden verlernen, dass es Python-Code-Tags gibt?
http://python-forum.de/viewtopic.php?f= ... 62#p172962

Der Code sieht ziemlich unübersichtlich aus. Da habe ich wenig Lust, mir das genauer anzusehen.

An Deiner Stelle würde ich einfach mal eine Vokabel-Datei exakt so posten, wie Du sie vorliegen hast. (Es reichen da ja ein paar Zeilen, die aber genau das "seltsame" Verhalten mit Deinem Code zeigen)
encoding_kapiert = all(verstehen(lesen(info)) for info in (Leonidas Folien, Blog, Folien & Text inkl. Python3, utf-8 everywhere))
assert encoding_kapiert
rads
User
Beiträge: 153
Registriert: Freitag 26. März 2010, 15:51

Ich gebe zu, wirklich verstanden habe ich nicht was du willst

aber wenn du eine liste in der Form haben willst

wert1-1,wert1-2, wert1-3
wert2-1, wert-2-2
wert 3-3

Als ein mehrdimensionales array
sprich, list = [(x,y,c),(c,y),(b)]


nach der oben aufgeführten Ausgabe hast du aber nur ein eindimensionales array, also

wert1-1,wert1-2, wert1-3,wert2-1, wert-2-2,wert 3-3
sprich, list = [x,y,c,c,y,b]

Zumindest verstehe ich den oben aufgeführten text so.

Ansonsten, wenn du dur einen Wertstream in Form eines csv (comma separated values) hast,
einfach String.split(';') und nach gewünschten Werten in der Ausgabe ein \n\r anhängen.
An sich machst du sowas ja im Code, wahrscheinlich hier einfach ein fehler? Zur Kontrolle
einfach mal den Wert nicht im Editor anschauen, sondern in ursprungsform um zu kontrollieren
ob die \n an der richtigen Stelle sind.

Wie gesagt, wenn ich das Problem überhaupt richtig verstehe...

Grüße
bjoernh
User
Beiträge: 20
Registriert: Donnerstag 27. Mai 2010, 15:45

Hi, ich hab den Kram einfach nochmal geschrieben und jetzt klappt es. Nur zur Info:
Ich habe im n-ten Tab von dem input für find_heisig sowas wie

百货公司
价钱
合理
...

für die erste Zeile gibt heisig_find "hundred, freight, public, director" zurück, so das ich insgesamt

百货公司 hundred, freight, public, director
价钱 value, Münze
合理 fit, logic
...
erhalte.

hier meine neue heisig_find-Funktion:

Code: Alles auswählen

def heisig_find(hanzi, n):			#returns heisig-keywords from n-th tab of "vocab"
	hanzi_tabsplit = hanzi.split('\t')
	heisig_string = " "
	for x in hanzi_tabsplit[n]:
		for heisig_line in heisig_file.readlines(): 
			heisig_line_tabsplit = heisig_line.split('\t')
			heisig_line_tabsplit[1]=heisig_line_tabsplit[1].strip()
			index = x.find(heisig_line_tabsplit[0])
			if index!=-1:
				heisig_string = heisig_string + ", " + heisig_line_tabsplit[1]
		heisig_file.seek(0)
	heisig_string=heisig_string.lstrip(", ") + '\n'
	return heisig_string
BlackJack

@bjoernh: Ich glaube einiges von dem Folgenden hatten wir schon einmal.

Es ist zu weit eingerückt -- Zeilen sind dadurch länger als 80 Zeichen.

Der Test ob eine Zeichenkette in einer anderen vorhanden ist, geht mit dem ``in``-Operator kürzer, einfacher, und lesbarer.

Das mit den Indexen 0 und 1 ist schlecht lesbar -- wenn bei dem `split()` immer zwei Elemente herauskommen, kann man die auch an Namen binden.

Die Datei wird mit `readlines()` mehrfach komplett in den Speicher gelesen. Warum? Wenn Du sie sowieso komplett in den Speicher liest, kannst Du das auch *einmal* vor den beiden Schleifen tun. Und wo kommt `heisig_file` eigentlich her? Das sollte eigentlich nicht bekannt sein!?

Die Art wie das Ergebnis mit den Kommas erzeugt wird, ist umständlich und ineffizient. Ausserdem ist der `lstrip()`-Aufruf so wie er da steht verwirrend und könnte darauf hindeuten, dass die Methode falsch verstanden wurde. Bei so etwas würde ich das Argument so schreiben, dass man es den "offensichtlichen" Irrtum von einigen Anfängern nicht unterstützt wenn sie den Quelltext lesen und ein `lstrip(' ,')` daraus machen. Letztlich ist aber wie gesagt die Art wie die Zeichenkette da zusammengesetzt wird kein idiomatisches Python. Dafür gibt es die `join()`-Methode auf Zeichenketten.

Wenn die Datei sowieso komplett in den Speicher gelesen wird, und wenn man den Quelltext ändert, so dass das nur *einmal* passiert, kann man sich natürlich sparen diese Zeilen jedesmal auf's neue am '\t' zu splitten und das auch nur einmal beim einlesen machen.

Das kann dann letztendlich hierzu führen (ungetestet):

Code: Alles auswählen

def heisig_find(heisig_file, hanzi, n):
    """returns heisig-keywords from n-th tab of "vocab"
    """
    result = list()
    hanzi_n = hanzi.split('\t')[n]
    heisigs = [s.strip().split('\t') for s in heisig_file]
    for x in hanzi_n:
        result.extend(keyword for needle, keyword in heisigs if needle in x)
    return ' %s\n' % ', '.join(result)
Antworten