Float-Formatierungsoperator mit Vorzeichen

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
calo
User
Beiträge: 47
Registriert: Freitag 8. Dezember 2006, 21:35
Wohnort: Stuttgart

Mittwoch 8. August 2012, 09:00

Hallo Zusammen,

folgendes Problem: ich habe zwei listen a und b. a besteht aus konstanten Zahlenwerten, die positiv oder negativ sein können. b hingegen aus Variablen-Namen. Beide Listen möchte ich in einem String zu einer Funktion verbinden:

Code: Alles auswählen

>>> a = [-.1, -.2, .03]
>>> b = ["eins", "zwei", "drei"]
>>> print "%f * %s + %f * %s + %f * %s" % (a[0], b[0], a[1], b[1], a[2], b[2])
-0.100000 * eins + -0.200000 * zwei + 0.030000 * drei
Raus kommen sollte aber folgendes Ergebnis:

Code: Alles auswählen

-0.100000 * eins -0.200000 * zwei + 0.030000 * drei
Mir geht es um das Vorzeichen im 2. Term (obere Ausgabe: "+ -"). Ich möchte verhindern , dass Python beide Vorzeichen ausgibt. Es würde schon helfen, wenn ich mit dem Formatierungsoperator die Ausgabe des Vorzeichens immer erzwingen könnte (also auch im Positiven Fall). Dann könnte ich im Formatierungsstring die Plussymbole einfach weglassen. Kennt ihr da eine Möglichkeit?

Vielen Dank im Voraus.
Zuletzt geändert von calo am Donnerstag 9. August 2012, 04:23, insgesamt 1-mal geändert.
deets

Mittwoch 8. August 2012, 09:13

So einfach geht das nicht. Du musst schon selbst den Operator entfernen aus dem String, und durch eine Variable ersetzen, die du abhaengig vom Vorzeichen des Faktors setzt. Und selbigen dann negieren, damit die Ausgabe da kein Vorzeichen reinschreibt. Also etwa grob sowas (ungetestet):

Code: Alles auswählen

a = [-.1, -.2, .03]
ops_and_factors = [("+", f) if f >= 0 else ("-", -f) for f in a]
Benutzeravatar
Sr4l
User
Beiträge: 1091
Registriert: Donnerstag 28. Dezember 2006, 20:02
Wohnort: Kassel
Kontaktdaten:

Mittwoch 8. August 2012, 09:15

Musst du einfach nur in der Dokumentation bei format gucken bzw format minilanguage.

Code: Alles auswählen

In [1]: "{:+f} {:+f}".format(100.12, -11,32)
Out[1]: '+100.120000 -11.000000'
Benutzeravatar
snafu
User
Beiträge: 5901
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Mittwoch 8. August 2012, 09:20

Ein Vorzeichen lässt sich mittels "%+d" erzwingen. Aber für ein Leerzeichen dazwischen wüsste ich keine Lösung. Du wirst dir wahrscheinlich mit einer eigenen Lösung behelfen müssen.
BlackJack

Mittwoch 8. August 2012, 09:22

@calo: Wenn Du Quelltext zeigst der aussieht als wäre er aus einer Python-Shell kopiert, dann sollte das auch wirklich der Fall sein, und nicht etwas was Du Dir ausgedacht hast. Das hier kommt da nämlich tatsächlich bei heraus:

Code: Alles auswählen

In [105]: a = [-.1, -.2, .03]

In [106]: b = ["eins", "zwei", "drei"]

In [107]: print "%d * %s + %d * %s + %d * %s" % (a[0], b[0], a[1], b[1], a[2], b[2])
0 * eins + 0 * zwei + 0 * drei
karolus
User
Beiträge: 100
Registriert: Samstag 22. August 2009, 22:34

Mittwoch 8. August 2012, 09:52

Hallo
so könnts was werden:

Code: Alles auswählen

print " ".join(["{0: =+6.2f} * {1:s}".format( *elem )for elem in zip(a, b)])
Karo
Benutzeravatar
snafu
User
Beiträge: 5901
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Mittwoch 8. August 2012, 10:53

Lässt sich sogar noch ein bißchen kürzer schreiben:

Code: Alles auswählen

print ' '.join('{:=+6.2f} * {}'.format(*elem) for elem in zip(a, b))
Unschön finde ich daran nur, dass dies bei 2 Stellen vor dem Komma schon wieder nicht wie gewünscht funktioniert, da an der Stelle, wo die 6 steht, der Abstand zum Vorzeichen geregelt wird. Genau genommen ist es die "Mindestzeichenzahl". Alles, was darunter liegt, wird mit Leerzeichen aufgefüllt. Eine einstellige Zahl mit zwei Nachkommastellen und Vorzeichen hat also 5 Stellen. Um auf das Minimum zu kommen, wird 1 Leerzeichen eingefügt. Wenn aber jetzt statt 0.1 zum Beispiel 10.1 genutzt wird, dann braucht kein Leerraum mehr eingefügt werden, um auf die Mindestzahl zu kommen. Das lässt sich nur lösen, indem man für die 6 eine 7 nimmt. Dann aber wird überall eine Mindestzahl von 7 genommen, sodass an den übrigen Stellen 2 Leerzeichen dazu kämen. Insgesamt also ein ziemlich unflexibler Ansatz.
Benutzeravatar
gkuhl
User
Beiträge: 600
Registriert: Dienstag 25. November 2008, 18:03
Wohnort: Hong Kong

Mittwoch 8. August 2012, 11:11

@calo: Geht es dir um symbolische Mathematik? Dann könntest du dir mal "sympy" anschauen:

Code: Alles auswählen

In [26]: import sympy as sy

In [27]: a = sy.Matrix([-.1, -.2, .03])

In [28]: eins = sy.Symbol('eins')

In [29]: zwei = sy.Symbol('zwei')

In [30]: drei = sy.Symbol('drei')

In [31]: b = sy.Matrix([eins, zwei, drei])

In [32]: (a.T * b)[0]
Out[32]: 0.03*drei - 0.1*eins - 0.2*zwei
Grüße
Gerrit
calo
User
Beiträge: 47
Registriert: Freitag 8. Dezember 2006, 21:35
Wohnort: Stuttgart

Mittwoch 8. August 2012, 15:03

Hallo an Alle,

vielen Dank für die vielen Tipps. Ich werd' sie gleich ausprobieren :lol:

@Backjack, sorry. Ich hatte tatsächlich den Code aus einer Shell kopiert, aber versehentlich die falsche Zeile genommen. Zeile 3 sollte natürlich so aussehen:

Code: Alles auswählen

print "%f * %s + %f * %s + %f * %s" % (a[0], b[0], a[1], b[1], a[2], b[2])
...und in zukunft dann so :lol: (auf evtl. fehlende Leerzeichen kommt es mir nicht an):

Code: Alles auswählen

print "%+f * %s %+f * %s %+f * %s" % (a[0], b[0], a[1], b[1], a[2], b[2])
Antworten