Unicode in Listen ausgeben lassen.(Listen , Unicode , Print)

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
Juri
User
Beiträge: 4
Registriert: Samstag 16. November 2013, 15:16

Hi leute ,
Und Zwar habe ich Folgenes Problem ich möchte den Unicode "\x03" in einer Liste speichern , doch wenn ich diese
Liste dann wieder ausgebe . Wird nicht das Zeichen gezeigt sondern nur der String "\x03" .

Code: Alles auswählen

import sys

HEARTS = "\x03"
print(HEARTS)     # Hier wird das richtige Zeichen angezeigt . 

Liste=[HEARTS]
print(Liste)      #  Und hier wird nur der String angezeigt . 

Danke im Vorraus Juri
Sirius3
User
Beiträge: 17753
Registriert: Sonntag 21. Oktober 2012, 17:20

Hallo Juri,
wenn Du mit print eine Liste ausgeben willst, muß dies erst in einen String umgewandelt werden. Das geschieht indem die Repräsentation der Listenelemente durch Komma getrennt zwischen eckige Klammern gepackt wird.
Die Repräsentation eines Strings sind die Zeichen des Strings, solange sie im ASCII-Bereich 32 bis 127 liegen oder eben die '\x12'-Schreibweise in Anführungszeichen gepackt. Das was Du beobachtest, ist also das ganz normale Verhalten. Die meisten Objekte außer Zahlen und Strings sind auch nur zu Debug-Zwecken zur Ausgabe mit print gedacht.
Juri
User
Beiträge: 4
Registriert: Samstag 16. November 2013, 15:16

Hi Siriius3
erst danke für die schnelle antwort .
Also meinst du ich muss es erst so verpacken damit ich mein Zeichen ausgeben bekomme oder hab ich das jetzt falsch verstanden ?

Code: Alles auswählen

print(str(["\x03"]))
Sirius3
User
Beiträge: 17753
Registriert: Sonntag 21. Oktober 2012, 17:20

Hi Juri,
Das »str« wird automatisch auf jedes Argument von »print« angewendet, das mußt Du also nicht explizit tun.
Was willst Du eigentlich machen?
Juri
User
Beiträge: 4
Registriert: Samstag 16. November 2013, 15:16

Für ein Kartenspiel will ich eine Liste erstellen die 32 Karten enthält (Herz Kreuz Pike Karo von 7 bis Ass )
nur mein Problem ist das wenn ich diese Liste oder Elemente der Liste ausgeben will wird mir nicht das Zeichen Herz,7 angezeigt sondern nur der code
also \x03,7 was natürlich nicht sehr schön aussieht.
Sirius3
User
Beiträge: 17753
Registriert: Sonntag 21. Oktober 2012, 17:20

Bevor Du die Liste ausgeben kannst, mußt Du sie erst in einen String konvertieren. Ungefähr so:

Code: Alles auswählen

print("Du hast folgende Karten: {}".format(", ".join(karten)))
wobei »karten« eine Liste mit Strings sein muß. Sind die Elemente etwas anderes, mußt Du diese auch noch in einen String umwandeln.
Benutzeravatar
diesch
User
Beiträge: 80
Registriert: Dienstag 14. April 2009, 13:36
Wohnort: Brandenburg a.d. Havel
Kontaktdaten:

Bei

Code: Alles auswählen

print(Liste) 
werden die Listenelemente mit ihrer Darstellung gemäß "repr()" ausgegeben.

Du musst die also entweder den Ausgabe-String selbst zusammenbauen, z.B.

Code: Alles auswählen

print(''.join(Liste))
oder dir eine eigene Klasse für die Karten schreiben, deren Methode ``__repr__`` die gewünschte Darstellung liefert.
http://www.florian-diesch.de
BlackJack

Wobei der das Unicode im Titel und das `print()` mit Klammern hier irreführend ist, denn soweit ich das sehe hat das hier nichts mit Unicode zu tun und wenn das mit '\x03' tatsächlich so funktioniert, dann dürfte es sich um Python 2 handeln wo ``print`` keine Funktion sondern ein Schlüsselwort ist.

Wenn bei dem *Byte*-Wert 3 ein Herz angezeigt wird, dann handelt es sich sehr wahrscheinlich um eine DOS-Codepage. Das entsprechende *Unicode*-Zeichen 'BLACK HEART' hätte nämlich den Wert '\u2665'. Wobei das im Grunde auch nicht ganz stimmt, weil die Codepage 850, um die es hier wahrscheinlich geht, gar kein Herz kennt. Die Bytewerte 1-31 sind nicht wirklich definiert, aber der Zeichensatz von VGA-Grafikkarten zeigt an der Stelle 3 üblicherweise ein Herz und die drei Folgezeichen üblicherweise die anderen Spielkartenfarben.
Hellstorm
User
Beiträge: 231
Registriert: Samstag 22. Juni 2013, 15:01

Du kannst jedes Zeichen auch einfach direkt in den Quellcode schreiben. Das macht das ganze wesentlich einfacher zu lesen, weil du dich ja nicht erst erinnern musst, was denn ein bestimmter Codepunkt bedeutet.

Also z.B.

Code: Alles auswählen

print("♥")
BlackJack

@Hellstorm: Die Klammern gehören da nicht hin! ``print`` ist in Python 2 keine Funktion.

Das funktioniert nur wenn der Quelltext in der Kodierung gespeichert ist, die vom Programm welches die Ausgabe entgegen nimmt erwartet wird. Also in diesem Fall eine DOS-Codepage wie CP850. Das kann nicht jeder Editor. Die nächste Frage ist wie der Editor mit dem Bytewert 3 als Zeichen umgeht, weil das in den meisten Kodierungen ein Steuerzeichen ist, oder nicht definiert ist. Wie in CP850 zum Beispiel. Es ist also nicht sehr wahrscheinlich, dass dort tatsächlich ein Herz im Quelltext angezeigt wird. Das würde ich eigentlich nur von einem DOS-Texteditor im Textmodus, also in einer Konsole erwarten. Und selbst dort dürften das einige, oder sogar viele Editoren als Steuerzeichen irgendwie anders darstellen.
Benutzeravatar
cofi
Python-Forum Veteran
Beiträge: 4432
Registriert: Sonntag 30. März 2008, 04:16
Wohnort: RGFybXN0YWR0

Alternativ zu BlackJacks anpassen auf Python 2, kann man den Interpreter auch auf Python3 anpassen mit `from __future__ import unicode_literals, print_function`.

Dann muss man "nur noch" mit dem Ausgabe-Encoding aufpassen.
BlackJack

@cofi: Das wird dem OP wohl leider nicht helfen, weil es in den bei uns üblichen CP...-Codepages kein Herz gibt, auch wenn das in der Konsole unter Windows bei der Ausgabe vom Bytewert 3 angezeigt wird. Das Problem wird das hier sein:

Code: Alles auswählen

In [25]: u'♥'
Out[25]: u'\u2665'

In [26]: u'♥'.encode('cp850')
---------------------------------------------------------------------------
UnicodeEncodeError                        Traceback (most recent call last)
/home/bj/<ipython-input-26-8e60cd1269a7> in <module>()
----> 1 u'♥'.encode('cp850')

/usr/lib/python2.7/encodings/cp850.pyc in encode(self, input, errors)
     10 
     11     def encode(self,input,errors='strict'):
---> 12         return codecs.charmap_encode(input,errors,encoding_map)
     13 
     14     def decode(self,input,errors='strict'):

UnicodeEncodeError: 'charmap' codec can't encode character u'\u2665' in position 0: character maps to <undefined>
Benutzeravatar
cofi
Python-Forum Veteran
Beiträge: 4432
Registriert: Sonntag 30. März 2008, 04:16
Wohnort: RGFybXN0YWR0

Ja, genau das meinte ich mit dem 2. Satz ;)
Hellstorm
User
Beiträge: 231
Registriert: Samstag 22. Juni 2013, 15:01

BlackJack hat geschrieben:@Hellstorm: Die Klammern gehören da nicht hin! ``print`` ist in Python 2 keine Funktion.
Naja, bin davon ausgegangen, dass Juri Python 3 nutzt. Er schreibt ja:

Code: Alles auswählen

print(HEARTS)     # Hier wird das richtige Zeichen angezeigt . 
Also gehören da ja doch Klammern hin (er benutzt ja selber auch welche). Naja, du schreibst, dass es im vorliegenden Fall wohl Python 2 ist, ich meinte das allerdings eher allgemein auf Quelltexte bezogen (Dass der Quelltext dann die richtige Kodierung haben sollte, habe ich vorausgesetzt. Normalerweise ist es ja sowieso anzuraten, den Quelltext in UTF-8 zu speichern). Bei Python 2 geht das natürlich auch, dann halt ohne Klammern und mit u"...".
diesch hat geschrieben:Bei
Du musst die also entweder den Ausgabe-String selbst zusammenbauen, z.B.

Code: Alles auswählen

print(''.join(Liste))
oder dir eine eigene Klasse für die Karten schreiben, deren Methode ``__repr__`` die gewünschte Darstellung liefert.
Hierzu habe ich mal eine Frage. Bei http://docs.python.org/3.3/reference/datamodel.html steht folgendes zu __repr__:
This is typically used for debugging, so it is important that the representation is information-rich and unambiguous.
Heißt das, dass man __repr__ eher nur für internes Debugging, aber nicht für die „offizielle“ Ausgabe benutzt? Auf der Webseite wird nämlich etwas später noch __str__ beschrieben, was mir irgendwie ähnlich erscheint. Was genau ist denn jetzt der Unterschied und was soll man denn jetzt benutzen? :K
Danke schon einmal für die Antwort :)
BlackJack

@Hellstorm: Da Juri kein Python 3 benutzt gehören die Klammern auch bei ihm nicht zum ``print``. Und eine Antwort für Python 3 nutzt ihm nicht viel, denn bei dem was Du gezeigt hast, würde man unter Python 3 in die Kodierungsausnahme laufen weil es das Herz nun mal nicht in CP… gibt, sondern nur im VGA-Zeichensatz, was aber nun mal keine Kodierung ist.

An der Stelle wäre interessant ob man das in Python 3 *überhaupt* vernünftig hinbekommt ohne grössere Verrenkungen. Wahrscheinlich müsste man da so etwas schreiben wie ``sys.stdout.buffer.write(b'\x03')``. Bin jetzt zu faul in der Dokumentation nachzulesen ob `buffer` Bestandteil der offiziellen API ist. :-)

Die Beschreibung zu `__repr__()` ist doch deutlich: Ja, die Methode sollte eine Darstellung für Programmierer erstellen, nicht für Endbenutzer eines Programms.

Von `__format__()` einfach die Finger lassen wenn Du nicht weisst was das macht. Das ist zum erstellen einer Zeichenkette mit der Möglichkeit für den Aufrufer das mit einer Zeichenkette mit Optionen irgendwie zu beeinflussen. Braucht man eher selten. Wenn Du etwas zu `__repr__()` vergleichbares suchst, dann ist das `__str__()`. Das ist die Methode die aufgerufen wird wenn das Objekt in einer Zeichenkette umgewandelt werden soll, also zum Beispiel bei `str()`, `format()` und `str.format()` ohne Optionen im Platzhalter, oder `print()`.
Hellstorm
User
Beiträge: 231
Registriert: Samstag 22. Juni 2013, 15:01

BlackJack hat geschrieben:@Hellstorm: Da Juri kein Python 3 benutzt gehören die Klammern auch bei ihm nicht zum ``print``. Und eine Antwort für Python 3 nutzt ihm nicht viel, denn bei dem was Du gezeigt hast, würde man unter Python 3 in die Kodierungsausnahme laufen weil es das Herz nun mal nicht in CP… gibt, sondern nur im VGA-Zeichensatz, was aber nun mal keine Kodierung ist.

An der Stelle wäre interessant ob man das in Python 3 *überhaupt* vernünftig hinbekommt ohne grössere Verrenkungen. Wahrscheinlich müsste man da so etwas schreiben wie ``sys.stdout.buffer.write(b'\x03')``. Bin jetzt zu faul in der Dokumentation nachzulesen ob `buffer` Bestandteil der offiziellen API ist. :-)
Ich hab zugegebenermaßen nur seinen ersten Beitrag überflogen, da sah das so aus als ob er P3 benutzt. Naja, dann korrigiere ich mich und er soll print u"♥" schreiben :D
BlackJack hat geschrieben: Die Beschreibung zu `__repr__()` ist doch deutlich: Ja, die Methode sollte eine Darstellung für Programmierer erstellen, nicht für Endbenutzer eines Programms.

Von `__format__()` einfach die Finger lassen wenn Du nicht weisst was das macht. Das ist zum erstellen einer Zeichenkette mit der Möglichkeit für den Aufrufer das mit einer Zeichenkette mit Optionen irgendwie zu beeinflussen. Braucht man eher selten. Wenn Du etwas zu `__repr__()` vergleichbares suchst, dann ist das `__str__()`. Das ist die Methode die aufgerufen wird wenn das Objekt in einer Zeichenkette umgewandelt werden soll, also zum Beispiel bei `str()`, `format()` und `str.format()` ohne Optionen im Platzhalter, oder `print()`.
Da war ich jetzt nur etwas verwirrt, weil diesch __repr__() empfohlen hat. Nachdem ich __format__() entdeckt habe, hab ich dann auch etwas darüber __str__() entdeckt, siehe den Edit :D Und mich dann eben gefragt, was ich denn benutzen sollte... __str__ () kam mir dann auch am logischsten vor. Danke für deine Erläuterung!

Danke übrigens zu deiner Erklärung mit „wenn das Objekt in einer Zeichenkette umgewandelt werden soll, also zum Beispiel bei `str()`,...“! Das hat mir gerade genau richtig bei einem Problem geholfen :)
Antworten