2012-04-03 9 views
0

Ich habe ein Django Queryset-Objekt namens data mit String-Schlüssel und Float-Werte.Django/Python Convert Float während Listenverstehen

Ich möchte alle Floats auf 2 Dezimalstellen konvertieren.

Wenn ich dies tun:

>>> param1_values = [d[param1] for d in data] 
>>> param1_values[:5] 
[26.1, 24.6, 26.2444444444444, 27.3103448275862, 26.7576923076923] 

... was in Ordnung ist, aber ich muss auf zwei Dezimalstellen schweben. Jedoch

, wenn ich dies tun:

>>> param1_values = ["%.2f" % d['mean_air_temp'] for d in data] 
>>> param1_values[:5] 
['26.10', '24.60', '26.24', '27.31', '26.76'] 

Die Zahlen sind, was ich wollte, aber sie sind in Strings umgewandelt! Warum passiert das und wie löse ich es?

Jede Hilfe wird geschätzt.

+0

Was möchten Sie erreichen? Welchen Zweck hat es, die Zahlen in gerundeter Form zu speichern? –

+0

In Antwort auf Ihre andere Frage, * Warum tritt das auf? *, Tritt auf, weil, wenn das erste Argument zum '%' -Operator eine Zeichenkette ist (''% .2f'') das Ergebnis immer eine Zeichenkette, ähnlich Wie in einer anderen Sprache könnten Sie 'printf' verwenden. – kojiro

Antwort

4

Sie können mit dem eingebauten in round Funktion:

param1_values = [round(d[param1], 2) for d in data] 

Hinweis: Das Verhalten von rund() für Schwimmer überraschend sein kann: für Beispiel rund (2.675, 2) 2,67 gibt stattdessen der erwarteten 2.68. Diese ist kein Fehler: Es ist ein Ergebnis der Tatsache, dass die meisten Dezimalbrüche nicht genau wie ein Float dargestellt werden können. Weitere Informationen finden Sie unter Floating Point Arithmetic: Issues and Limitations.

Dies scheint genau genug für Ihren Anwendungsfall zu sein. Wenn Sie eine genauere Antwort benötigen, lesen Sie Ignacio's Antwort mit Dezimal.

+0

Nein, du kannst nicht. Aber ein guter erster Versuch. –

+0

Perfekter Dank! –

+0

@ IgnacioVazquez-Abrams: Und warum sollte das sein? Ein solcher Kommentar ist kaum hilfreich (auch wenn er richtig sein könnte). –

0

Brauchen Sie wirklich die Werte gerundet, oder möchten Sie nur zwei Werte nach dem Dezimalpunkt anzeigen, wenn die Werte in einer Vorlage angezeigt werden? Wenn Sie an einem Anzeigeproblem arbeiten, verwenden Sie die 'floatformat' filter. Wenn Sie das erreichen möchten, glaube ich, dass Sie beim Durchlaufen der Liste "listitem | floatformat: -2" verwenden können, um das gewünschte Ergebnis zu erzielen. Wenn Sie stattdessen die abgerundete Version in Python speichern und verwenden möchten, werden Sie not have an easy time of it.

+0

Lies noch einmal den ursprünglichen Beitrag und du möchtest vielleicht "listitem | floatformat: 2". Dies zeigt zwei Werte nach der Dezimalstelle an, auch wenn beide Null sind. Die Option '-2' im Original zeigt nur Werte nach dem Dezimalzeichen an, wenn der vollständige Wert auf zwei Dezimalstellen gerundet werden muss. –

1

Aufgrund unavoidable inaccuracies in IEEE 754 floating point representation ist es unmöglich, dies zu lösen, während sie schwimmt.

>>> l = [26.1, 24.6, 26.2444444444444, 27.3103448275862, 26.7576923076923] 
>>> [decimal.Decimal(x).quantize(decimal.Decimal('0.1')) for x in l] 
[Decimal('26.1'), Decimal('24.6'), Decimal('26.2'), Decimal('27.3'), Decimal('26.8')] 

das entsprechende Feld in Django verwenden, wenn Sie diese speichern möchten ist DecimalField (es sei denn, Sie SQLite verwenden, aber das ist eine ganz andere Kessel der Fische).

+0

+1: Danke, dass du zurückkommst und dies tust. Er will Dezimalpunkte, also sollte es "dezimal. Dezimal ('0.01')" sein – sdolan