version python 2.7.1
ich lese mit modul xlrd eine excel und zwar jede Zeile in eine list.
das klappt und eine list sieht zB so aus.
[1.0, u'name', u'ist \u20ac', 100.0, u'und', u'\xfcber', u'200 \u20ac', u'%', '']
iteriere ich über die list und lasse mir jedes in IDLE mit print anzeigen sieht es auch noch gut aus.
1.0
name
ist €
100.0
und
über
200 €
%
so mein ziel war es nun diese Ausgabe
1.0
name
ist €
100.0
und
über
200 €
%
in eine test.txt zu schreiben.
mit dem befehl f = open(meinfile,'w') klappt es nicht, da System bringt meldung.
cant codec ascii usw........
ich frage mich wie die typen float und unicode zum beispiel die in der list enthalten sind ich so in eine txt datei schreiben kann wie ich die daten mit dem Auge sehen wenn ich die einzelnen listindexe mit print ausgebe im idle.
ich kapier das nicht.
ich hoffe mir kann einer helfen.
list in txt problem mit unicode
Wenn ich deinen kryptischen Text richtig verstanden habe, willst du:
Code: Alles auswählen
f.write('\n'.join(unicode(line) for line in deine_liste))
@python71: In der Liste sind Unicode-Objekte enthalten. Wenn Du Die in IDLE per ``print`` ausgibst ist das kein Problem, denn Python kann herausfinden welche Kodierung IDLE erwartet. Dateien haben aber keine Kodierung, also musst Du da explizit dafür sorgen, dass die Unicode-Zeichenketten in "Byte"-Ketten, also `str` umgewandelt werden.
@snafu: Wohl eher nicht. Es sind keine Zeilen in der Liste, der Name `line` passt also nicht. Und genau der Umstand dass das `unicode` ist, führt doch zum Fehler.
@snafu: Wohl eher nicht. Es sind keine Zeilen in der Liste, der Name `line` passt also nicht. Und genau der Umstand dass das `unicode` ist, führt doch zum Fehler.
@Blackjack
genau das is ja mein problem:
in idle z.B unicode 'test' kann ich in beide Richtungen umwandeln
>>> a =u'test'
>>> a.encode()
'test'
>>> _.decode()
u'test'
diesen unicode der in meiner List ist aber nicht dann komm fehlermeldung siehe unten.
>>> t = u'ist \u20ac'
>>> t.encode()
Traceback (most recent call last):
File "<pyshell#49>", line 1, in <module>
t.encode()
UnicodeEncodeError: 'ascii' codec can't encode character u'\u20ac' in position 4: ordinal not in range(128)
In der Zwischenzeit habe ich mal in der python doku gestöbert. Dort fand ich das modul codecs.
Mein code sieht nun so aus und er tut. Warum wieso kann ich nicht sagen aber er tut.
Zu Info ich bin absoluter Anfänger.
Danke jedenfalls
genau das is ja mein problem:
in idle z.B unicode 'test' kann ich in beide Richtungen umwandeln
>>> a =u'test'
>>> a.encode()
'test'
>>> _.decode()
u'test'
diesen unicode der in meiner List ist aber nicht dann komm fehlermeldung siehe unten.
>>> t = u'ist \u20ac'
>>> t.encode()
Traceback (most recent call last):
File "<pyshell#49>", line 1, in <module>
t.encode()
UnicodeEncodeError: 'ascii' codec can't encode character u'\u20ac' in position 4: ordinal not in range(128)
In der Zwischenzeit habe ich mal in der python doku gestöbert. Dort fand ich das modul codecs.
Mein code sieht nun so aus und er tut. Warum wieso kann ich nicht sagen aber er tut.
Zu Info ich bin absoluter Anfänger.
Code: Alles auswählen
#-*- coding: utf-8 -*-
#Open the workbook
# mit Python excel file lesen xlrd geht nur bis Python 2.7 und Excel muss ein xls file sein
import xlrd
import codecs
datei = xlrd.open_workbook('C:\\Test\\frank.xls')
tabelle = datei.sheet_by_index(0)
f = codecs.open('test.txt', encoding='utf-8', mode='w',buffering = 1)
for zeile in range(tabelle.nrows):
l = tabelle.row_values(zeile)
for i in range(0,tabelle.ncols):
print (l[i])
if type(l[i]) is unicode:
f.write (l[i])
else:
dummy = str(l[i])
f.write(dummy)
f.write('\n')
f.close()
Du musst in dem Fall beim Enkodieren auch die Kodierung mit angeben:
Ich habe in dem Zusammenhang etwas gebastelt, das ich für ein eigenes Projekt benötige: _stringutils.py. Es konvertiert übergreifend für Python 2 und Python 3 wahlweise in die native String-Form oder in die "alternative" Form (Unicode unter Python 2, Bytes unter Python 3). Dabei kommt es auch mit Objekten klar, die keine Strings sind (wie z.B. deine Zahlen). Eventuell hilft dir das. Ansonsten gibt es im schon von dir genannten Codecs-Modul aber auch noch ein paar Klassen, die hilfreich sein könnten. Habe mich ehrlich gesagt noch nicht so genau mit dem Modul beschäftigt.
Code: Alles auswählen
>>> t.encode('utf-8')
'ist \xe2\x82\xac'
@python71: Wenn Du einfach nur `encode()` oder `decode()` ohne Argument verwendest, dann wird 'ASCII' angenommen. Das fällt halt auf die Nase wenn irgend etwas ausserhalb des ASCII-Wertebereichs vorkommt. Du musst da schon eine konkrete Kodierung angeben. Für das Kodieren Eine, die alle Zeichen kodieren kann, und für das Dekodieren Diejenige, in der die Zeichen auch mal kodiert wurden.
Das `buffering`-Argument bei `codecs.open()` brauchst Du nicht angeben. Es sei denn Du willst etwas anderes als die Voreinstellung.
Anstelle von `range()` solltest Du `xrange()` verwenden und bei der inneren Schleife ist das wohl auch überflüssig, oder ist die Liste länger als ``tabelle.ncols``? Selbst dann würde ich wohl eher die Elemente aus der Liste ausschneiden (slicing) und direkt über die Elemente iterieren statt diesen unnötigen Index `i` mit zu schleppen.
Beim Typtest ist ein Problem: ``is`` vergleicht nicht auf Gleichheit, sondern auf Objektidentität. Und man testet da auch eher mit `isinstance()` statt mit `type()`.
Das `buffering`-Argument bei `codecs.open()` brauchst Du nicht angeben. Es sei denn Du willst etwas anderes als die Voreinstellung.
Anstelle von `range()` solltest Du `xrange()` verwenden und bei der inneren Schleife ist das wohl auch überflüssig, oder ist die Liste länger als ``tabelle.ncols``? Selbst dann würde ich wohl eher die Elemente aus der Liste ausschneiden (slicing) und direkt über die Elemente iterieren statt diesen unnötigen Index `i` mit zu schleppen.
Beim Typtest ist ein Problem: ``is`` vergleicht nicht auf Gleichheit, sondern auf Objektidentität. Und man testet da auch eher mit `isinstance()` statt mit `type()`.
Um darauf noch einzugehen: Wenn der OP über die Elemente seiner Liste iteriert, um das jeweils aktuelle Objekt mittels `print` auszugeben, dann sind das durchaus Zeilen für mich. So wie ich es verstanden habe, möchte er die Art der Konsolenausgabe genau so in der entsprechenden Datei haben.BlackJack hat geschrieben:@snafu: Wohl eher nicht. Es sind keine Zeilen in der Liste, der Name `line` passt also nicht.
Oder ging dein Einwand in die Richtung, dass ich bei der Benennung in der for-Schleife nicht ein Wort gewählt habe (etwa `elem`), welches die Objekte im Kontext der Liste beschreibt, sondern sie stattdessen nach ihrem Verwendungszweck (Zeile) benannt habe?
@snafu: So habe ich das gar nicht gesehen. Ich fand es verwirrend weil die Liste insgesamt ja eine Zeile mit Spaltenwerten darstellt -- jedenfalls in der Excel-Tabelle wo sie entnommen wurde. Also wäre eine passende Bezeichnung dafür vielleicht `row` und ein ``(line for line in row)`` bringt mich mental halt ein wenig ins schleudern.