Seite 1 von 2
Unerwartete Leerzeichen
Verfasst: Freitag 15. April 2011, 13:52
von peddy
Hallo,
ich habe volgenden simplen Code:
Code: Alles auswählen
max_gewicht = int(raw_input("Bitte das Zielgewicht eingeben: "))
for prozent in ( 75, 80, 85, 90, 95, 100 ):
print ((max_gewicht * prozent) / 100),
Die Ausgabe auf dem Bildschirm sieht so aus:
Bitte das Zielgewicht eingeben: 100
75 80 85 90 95 100
Woher kommen die Leerzeichen zwischen den Zahlen? Ich hätte diese nicht erwartet.
Re: Unerwartete Leerzeichen
Verfasst: Freitag 15. April 2011, 14:08
von snafu
Lass mal das Komma hinter dem print-Statement weg. Du weißt übrigens schon, dass print unter Python 2.x keine Klammern benötigt, da es keine Funktion ist?
Re: Unerwartete Leerzeichen
Verfasst: Freitag 15. April 2011, 14:10
von lunar
Die Leerzeichen werden durch das Komma verursacht, was Du wüsstest, wenn Du die
Dokumentation gelesen hättest.
Ab Python 2.6 kannst Du "print" mit "from __future__ import print_function" in eine Funktion umwandeln, und anschließend "print((max_gewicht * prozent) / 100, end='')" nutzen, um eine Ausgabe ohne Leerzeichen zu erhalten.
Re: Unerwartete Leerzeichen
Verfasst: Freitag 15. April 2011, 14:42
von peddy
snafu hat geschrieben:Lass mal das Komma hinter dem print-Statement weg. Du weißt übrigens schon, dass print unter Python 2.x keine Klammern benötigt, da es keine Funktion ist?
Das mit den Klammern ist mir bewusst. Ich dachte mir nur, dann wird die Formel optisch leichter lesbar. Das Komma habe ich drinen, weil ich die Ausgabe in einer Zeile möchte.
Da ich noch am Anfang stehe, möchte ich genau wissen, wie sich Python verhält. Deshalb auch dieser Thread.
Re: Unerwartete Leerzeichen
Verfasst: Samstag 16. April 2011, 11:41
von Leonidas
Ja, dann ist lunar's Lösung wohl die beste.
Re: Unerwartete Leerzeichen
Verfasst: Samstag 16. April 2011, 15:09
von mutetella
Oder aber einen Leerzeichen-freien string erzeugen:
Code: Alles auswählen
In [4]: max_gewicht = 100
In [5]: ''.join([str(max_gewicht * prozent / 100) for prozent in (75, 80, 85, 90, 95, 100)])
Out[5]: '7580859095100'
lunar hat geschrieben:Die Leerzeichen werden durch das Komma verursacht, was Du wüsstest, wenn Du die Dokumentation gelesen hättest.
Die Dokumentation schreibt unter anderem:
"A space is written before each object is (converted and) written, unless the output system believes it is positioned at the beginning of a line."
Bleibt für mich die Frage, warum hat man das so festgelegt? Welchen Sinn macht das Leerzeichen? Sollte man das Einfügen von Zeichen zum Zwecke der Formatierung nicht dem Entwickler überlassen? Speziell dieses Leerzeichen kommt mir immer schon ein wenig
spanisch vor...
mutetella
Re: Unerwartete Leerzeichen
Verfasst: Samstag 16. April 2011, 15:18
von BlackJack
@mutetella: Ich nehme mal an es hat sich einfach als praktisch erwiesen, weil man es in vielen Fällen da haben möchte das Leerzeichen. Beim Beispiel vom OP macht es ja zum Beispiel auch Sinn.
Re: Unerwartete Leerzeichen
Verfasst: Samstag 16. April 2011, 16:37
von Barabbas
Ich denke eher, dass das ein Implementierungsdetail ist: Das Komma dient für gewöhnlich ja dazu, mehrere Objekte voneinander zu trennen, wie etwa in:
Da möchte man sowas ja i.d.R. auch haben. Die Sache mit dem Zeilenumbruch scheint damit zusammen zu hängen - das man da aber notwendigerweise auch ein Leerzeichen haben möchte, glaube ich nicht. Nicht ohne Grund wurde das in Python3 ja auch anders gelöst - mit 'end=""' bekommst du ja kein Leerzeichen mehr.
Besten Gruß,
brb
Re: Unerwartete Leerzeichen
Verfasst: Sonntag 17. April 2011, 13:14
von mutetella
Barabbas hat geschrieben:Da möchte man sowas ja i.d.R. auch haben.
BlackJack hat geschrieben:..., weil man es in vielen Fällen da haben möchte das Leerzeichen.
In der Regel, ja. Ich empfinde aber eine Anweisung, die etwas tut, was man in vielen Fällen so haben möchte, als nicht ganz astrein. Bei
erwarte ich eigentlich eine Ausgabe '123'. Dass die Zahlen in strings umgewandelt werden ist ja schon Luxus. Dass aber gleich noch Leerzeichen eingefügt werden? Sollte IMHO nicht sein. Wer das möchte, sollte das dann auch mit einem formatstring machen. Wäre jedenfalls einfacher als der umgekehrte Fall, eine Ausgabe ohne Leerzeichen zu erreichen.
Bin ich allein mit meiner Meinung? Übersehe ich etwas?
mutetella
Re: Unerwartete Leerzeichen
Verfasst: Sonntag 17. April 2011, 13:27
von EyDu
Nur um es mit anderen Worte noch einmal auszudrücken: Du findest es nicht gut, wenn eine Funktion genau das tut, was man in den meisten Fällen haben möchte und damit den intuitiven Erwartungen des Benutzer entspricht? Stattdessen möchtest du umständliche Formatierung für den Standardfall und keine automatische umwandlung in Strings. Ich empfehle dir C
Da das Statement ``print`` heißt, sollte man davon auch mehr erwarten dürfen als einfaches aneinanderhängen von Strings oder der Ausgabe eines einzelen (formatieten) Strings.
Re: Unerwartete Leerzeichen
Verfasst: Sonntag 17. April 2011, 13:39
von BlackJack
@mutetella: ``print`` ist doch sowieso der komplette Luxus und ein ziemlich komischer Fremdkörper. Man bedenke auch den optionalen Teil die Ausgabe in eine Datei umzuleiten. Besonders "pythonisch" sieht das nicht aus.
Bei ``print 1, 2, 3`` erwarte ich Leerzeichen. War bei BASIC ja so ähnlich. Und nun? Das Argument mit dem Formatstring kann man genau so gut umkehren -- wer *keine* Leerzeichen möchte, kann ja einen Formatstring nehmen.
Re: Unerwartete Leerzeichen
Verfasst: Sonntag 17. April 2011, 13:47
von lunar
@mutetella: Du findest Anweisungen, die tun, was „in vielen Fällen so haben möchte“, als nicht astrein?! Bitte was? Du kreidest "print" an, dass sich die Anweisung verhält, wie Du erwartest?!
Wenn "print" nicht das tut, was Du möchtest, wieso benutzt Du es dann? Ausgabe ohne jegliche Automatismen kannst Du schließlich auch mit "sys.stdout.write()" bewerkstelligen, niemand zwingt Dich zu "print".
Natürlich ist "print" nicht optimal. Deswegen wurde "print()" ja mittlerweile als Funktion implementiert, bei der dieses Verhalten mit "sep" und "end" konfiguriert werden kann. Nur verhält sich diese Funktion ja auch meist so, wie man es intuitiv erwartet
Sorry, Du das Verhalten einer Anweisung kennst, ja sogar erwartest, aber nicht magst, und dennoch diese Anweisung nutzt, obwohl es das gewollte Verhalten in Form einer anderen Anweisung/Funktion (in diesem "sys.stdout.write()") bereits gibt, dann ist Dir irgendwie nicht mehr zu helfen.
Re: Unerwartete Leerzeichen
Verfasst: Sonntag 17. April 2011, 21:53
von mutetella
@lunar: Ich glaube, Du hast nicht wirklich verstanden, worum es mir geht. Wer bin ich, dass ich das Verhalten von 'print' fundiert kritisieren könnte? Ich möchte einfach gerne verstehen, weshalb manche Dinge so sind, wie sie sind. Und dass 'print' Leerzeichen einfügt, ohne dass das explizit so angegeben und damit gewollt ist, finde ich einfach merkwürdig.
Wenn ich eine, zugegebenermaßen sinnfreie Funktion
Code: Alles auswählen
def print_it(*exp):
sys.stdout.write(' '.join([str(e) for e in exp]))
schreibe, würde ich sicherlich einen Rüffel kassieren, weil die Funktion etwas eigenmächtig tut, das man doch besser so
Code: Alles auswählen
def print_it(*exp, **form):
separator = form.get('separator', ' ')
sys.stdout.write(separator.join([str(e) for e in exp]))
machen sollte.
Aber nun gut, 'print' als Funktion arbeitet ja inzwischen so, also lag ich mit meinem Gefühl wohl nicht so verkehrt...
Und nein: Es geht mir nicht darum, Recht zu haben. Ich bin eher ein wenig zwanghaft, wenn es darum geht, mir unverständliches erklärt zu bekommen...
mutetella
EDIT: 'print_it' mit 'separator'-Parameter korrigiert...
Re: Unerwartete Leerzeichen
Verfasst: Sonntag 17. April 2011, 22:28
von BlackJack
@mutetella: Ich verstehe nicht wieso die Leerzeichen nicht gewollt sein sollen? Wenn sie nicht eingefügt werden, müsste man sie als extra "Argumente" angeben: ``print 1, ' ', 2, ' ', 3``. Das wäre ziemlich nervig. Zeichenkettenformatierung wäre keine Alternative, denn dann hätte man sich ``print`` auch komplett sparen können. Die Möglichkeit mehrere Argumente mit Kommata angeben zu können ist ausser dem Zeilenende-Zeichen ja sonst das einzige, was ``print`` vom Aufruf der `write()`-Methode auf `sys.stdout()` (oder einem anderen Dateiobjekt) unterscheidet.
Re: Unerwartete Leerzeichen
Verfasst: Sonntag 17. April 2011, 22:35
von EyDu
Man könnte ``print`` natürlich auch ``print_with_space_between_each_value_and_newline`` unbenennen, aber das wird dann langsam unpraktisch ^^ Außerdem ist das Verhalten gut
dokumentiert.
Re: Unerwartete Leerzeichen
Verfasst: Sonntag 17. April 2011, 22:49
von mutetella
BlackJack hat geschrieben:Ich verstehe nicht wieso die Leerzeichen nicht gewollt sein sollen?
Nun ja, ich kann mir durchaus Fälle vorstellen, in denen es gewollt ist, dass direkt am Vorgängerelement 'weitergeprintet' wird.
Aber wie so oft: Ist wohl Ansichtssache. Ich jedenfalls finde es nicht ganz richtig, wenn ich eine Liste ohne Leerzeichen übergebe und einen String mit Leerzeichen zurückbekomme. Auch wenn das in 90 % der Fälle vielleicht so gewollt ist.
Bleibt für mich die Erkenntnis, dass 'print' als Funktion irgendwie 'ehrlicher' ist...
Re: Unerwartete Leerzeichen
Verfasst: Sonntag 17. April 2011, 23:19
von BlackJack
@mutetella: Ich verstehe Deine Argumentation echt überhaupt nicht. Wenn in 90% der Fälle ein Leerzeichen gewollt ist, hättest Du trotzdem lieber eine Anweisung gehabt die nur in 10% der Fälle benutzbar ist!? Wie sinnlos ist *das* denn?
Re: Unerwartete Leerzeichen
Verfasst: Montag 18. April 2011, 06:45
von Darii
mutetella hat geschrieben:BlackJack hat geschrieben:Ich verstehe nicht wieso die Leerzeichen nicht gewollt sein sollen?
Nun ja, ich kann mir durchaus Fälle vorstellen, in denen es gewollt ist, dass direkt am Vorgängerelement 'weitergeprintet' wird.
Aber wie so oft: Ist wohl Ansichtssache. Ich jedenfalls finde es nicht ganz richtig, wenn ich eine Liste ohne Leerzeichen übergebe und einen String mit Leerzeichen zurückbekomme.
Nein, du übergibt eine Auflistung mit Kommata. Eigentlich müsstest du dich wundern, dass die Kommas nicht mit ausgegeben werden. Ist schließlich ein Tupel. Keine Leerzeichen ist genauso willkürlich wie die Verwendung von Leerzeichen.
Re: Unerwartete Leerzeichen
Verfasst: Montag 18. April 2011, 09:48
von mutetella
@BlackJack:
Es geht nicht darum, was ich will oder nicht. Es ist nur so, dass ich gerade auch hier in diesem Forum immer wieder darauf hingewiesen wurde, wenn eine Funktion zu viel, ich nenne es mal 'Eigendynamik', entwickelt. Und sollte etwas sowohl so wie auch anderst gelöst werden können, sollte die Entscheidung darüber nicht fest in die Funktion implementiert sein.
Ich weiß nicht, in welche Richtung diese Diskussion gehen würde, wenn sich der Entwickler von 'print' dafür entschieden hätte, zwischen einzelne Elemente kein Leerzeichen einzufügen.
Darii hat geschrieben:Eigentlich müsstest du dich wundern, dass die Kommas nicht mit ausgegeben werden. Ist schließlich ein Tupel. Keine Leerzeichen ist genauso willkürlich wie die Verwendung von Leerzeichen.
Die Kommas separieren die einzelnen Elemente des Tuples. Somit haben die mit einer möglichen Ausgabe überhaupt nichts zu tun. Eben genauso wenig, wie ein Leerzeichen. Sowohl das eine wie das andere finde ich willkürlich. An das Leerzeichen haben wir uns allenfalls gewohnt, deshalb 'erwarten' wir es vielleicht.
Aber letztlich geht es mir gar nicht so sehr darum, wie 'print' arbeitet. Lässt sich eh' nicht mehr ändern und ist ab python3 sowieso in meinem Sinne geändert...
Mit geht es vielmehr darum, wie weit eine Funktion etc. 'mitdenken' soll oder darf. Nur so weit, wie es in
jedem Fall Sinn macht oder auch so weit, wie es
in vielen Fällen Sinn macht ...?
mutetella
Re: Unerwartete Leerzeichen
Verfasst: Montag 18. April 2011, 10:00
von BlackJack
``print`` ist in Python 2.x keine Funktion! Damit gelten dafür auch nicht einfach so Entwurfskriterien für Funktionssignaturen. Ich würde auch nicht sagen, dass die Kommata die Elemente eines Tupels trennen -- das ist komplett eigene Syntax. Denn bei einem Tupel kann man nicht etwas nach dem Muster ``>>object`` als erstes Element schreiben und ein Komma nach dem letzten Element macht bei einem Tupel keinen Unterschied, bei ``print`` schon.
Eine Funktion sollte soviel "mitdenken" wie es in den meisten Fällen Sinn macht, sprich es sollten sinnvolle Defaultwerte verwendet werden. Macht die `print()`-Funktion ja auch.