Zahlen formatieren

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.
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

OK, und hier nochmal die Variante für Python >v2.3

Code: Alles auswählen

import re

formatter_regex = re.compile("^ *\d*\D\d{1,3}|\d{1,3} *")
def formatter(number, format = "%.2f", decChar = ",", groupChar = "."):
    """
    Convert to required format
    by HarryH modify by Jens Diemer

    number =      number to convert
    format =      python string formatting (%)
    decChar =     decimal char for the converted format
    groupChar =   group char for the converted format

    For example:
    formatter(1234567890.987, "%.2f", ",", ".")
    ==> 1.234.567.890,99
    formatter( 1234567890.987, "%i")
    ==> 1.234.567.890

    """
    def reverse( string ):
        # ersatz für string[::-1] welches erst ab v2.3 gibt :(
        list = re.findall(".",string)
        list.reverse()
        return "".join( list )

    return reverse(
        groupChar.join(
            formatter_regex.findall(
                reverse( (format % number).replace(".", decChar) )
            )
        )
    )
Ich hab re.compile() außerhalb der Funktion gemacht, deswegen erübrigt sich der Parameter groupRange

Warum hast du die Funktion __formatter genannt? Was bedeuten die doppelten Unterstriche?
Zuletzt geändert von jens am Donnerstag 7. Juli 2005, 15:45, insgesamt 2-mal geändert.

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

jens hat geschrieben:OK, und hier nochmal die Variante für Python >v2.4
Du meinst wohl 2.3 denn 2.3 kennt schon [::-1].
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Leonidas hat geschrieben:Du meinst wohl 2.3 denn 2.3 kennt schon [::-1].
Oh :oops:

Hab ich oben korregiert...

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

Hi!

Und hier noch eine kleine Übersicht über das Laufzeitverhalten bei 10.000 Durchläufen:

Code: Alles auswählen

#!/usr/bin/env python
# -*- coding: iso-8859-1 -*-

import re

#----------------------------------------------------------------------
def format_number_1(
   number, 
   format = "%0.2f",
   decimal_char = ",",
   group_char = ".",
   group_range = 3
):
   """
   Nach einer Idee von Voges, HarryH und Jens.
   http://www.python-forum.de/viewtopic.php?t=371
   """
   
   def reverse(string):
      # ersatz für string[::-1] welches erst ab v2.3 gibt :(
      list = re.findall(".",string)
      list.reverse()
      return "".join(list)
   
   regex = re.compile(
      "^ *\d*\D\d{1,%s}|\d{1,%s} *" % (group_range, group_range)
   )
   
   return reverse(
      group_char.join(
         regex.findall(
            reverse( (format % number).replace(
               ".", decimal_char) 
            )
         )
      )
   )


#----------------------------------------------------------------------
def format_number_2(
   number, 
   format = "%0.2f",
   decimal_char = ",",
   group_char = ".",
   group_range = 3
):
   """
   Nach einer Idee von Milan.
   http://www.python-forum.de/viewtopic.php?t=371
   """

   def split(s, size = group_range):
      return map(lambda i: s[i:i + size], xrange(0, len(s), size))

   def reverse(s):
      l = map(None, s)
      l.reverse()
      return ('').join(l)

   num = (format % number).replace('.', decimal_char)
   int_part = num[:num.find(decimal_char)]
   return (
      reverse(
         group_char.join(
            split(reverse(int_part))
         )
      ) + num[num.find(decimal_char):]
   ).replace(" %s" % group_char, "  ")
   

if __name__ == "__main__":
   # Testen welche Funktion schneller ist
   
   import time
   
   zahlen = (
      66,
      1,
      2,
      3.4,
      -5.678,
      612345,
      612345.555,
      987654321.067
   )

   begin = time.time()
   
   for i in range(10000):
      for zahl in zahlen:
         x = format_number_1(zahl)

   print "1:", time.time() - begin
   print

   begin = time.time()

   for i in range(10000):
      for zahl in zahlen:
         x = format_number_2(zahl)
         
   print "2:", time.time() - begin
   print
Ergebnis:

Code: Alles auswählen

1: 4.18799996376
2: 2.64100003242
mfg
Gerold
:-)
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Halt, da fehlt noch die ursprüngliche Version und sowieso und überhaupt:

Code: Alles auswählen

#!/usr/bin/python
# -*- coding: UTF-8 -*-

import re

#----------------------------------------------------------------------

format_number_0a_regex = re.compile("^ *\d*\D\d{1,3}|\d{1,3} *")
def format_number_0a(number, format = "%.2f", decChar = ",", groupChar = "."):
    """
    Convert to required format
    number =      number to convert
    format =      python string formatting (%)
    decChar =     decimal char for the converted format
    groupChar =   group char for the converted format
    groupRange =  group range for the converted format

    For example:
    __formatter(1234567890.987, "%.2f", ",", ".", 3)
    ==> 1.234.567.890,99

    """
    form_num = groupChar.join(format_number_0a_regex.findall((format % number).replace(".", decChar)[::-1]))[::-1]
    return form_num

#----------------------------------------------------------------------

def format_number_0b(number, format = "%.2f", decChar = ",", groupChar = ".", groupRange = 3):
    """
    Convert to required format
    number =      number to convert
    format =      python string formatting (%)
    decChar =     decimal char for the converted format
    groupChar =   group char for the converted format
    groupRange =  group range for the converted format

    For example:
    __formatter(1234567890.987, "%.2f", ",", ".", 3)
    ==> 1.234.567.890,99

    """

    regex = re.compile("^ *\d*\D\d{1,%s}|\d{1,%s} *" % (groupRange, groupRange))
    form_num = groupChar.join(regex.findall((format % number).replace(".", decChar)[::-1]))[::-1]
    return form_num

#----------------------------------------------------------------------
format_number_1_regex = re.compile( "^ *\d*\D\d{1,3}|\d{1,3} *" )
def format_number_1(
   number,
   format = "%0.2f",
   decimal_char = ",",
   group_char = "."
):
   """
   Nach einer Idee von Voges, HarryH und Jens.
   http://www.python-forum.de/viewtopic.php?t=371
   """

   def reverse(string):
      # ersatz für string[::-1] welches erst ab v2.3 gibt :(
      list = re.findall(".",string)
      list.reverse()
      return "".join(list)

   return reverse(
      group_char.join(
         format_number_1_regex.findall(
            reverse( (format % number).replace(
               ".", decimal_char)
            )
         )
      )
   )

#----------------------------------------------------------------------
format_number_1_regex = re.compile( "^ *\d*\D\d{1,3}|\d{1,3} *" )
def format_number_1b(
   number,
   format = "%0.2f",
   decimal_char = ",",
   group_char = "."
):
   """
   Nach einer Idee von Voges, HarryH und Jens.
   http://www.python-forum.de/viewtopic.php?t=371
   """

   def reverse(s):
      # ersatz für string[::-1] welches erst ab v2.3 gibt :(
      l = map(None, s)
      l.reverse()
      return ('').join(l)

   return reverse(
      group_char.join(
         format_number_1_regex.findall(
            reverse( (format % number).replace(
               ".", decimal_char)
            )
         )
      )
   )


#----------------------------------------------------------------------
def format_number_2(
   number,
   format = "%0.2f",
   decimal_char = ",",
   group_char = ".",
   group_range = 3
):
   """
   Nach einer Idee von Milan.
   http://www.python-forum.de/viewtopic.php?t=371
   """

   def split(s, size = group_range):
      return map(lambda i: s[i:i + size], xrange(0, len(s), size))

   def reverse(s):
      l = map(None, s)
      l.reverse()
      return ('').join(l)

   num = (format % number).replace('.', decimal_char)
   int_part = num[:num.find(decimal_char)]
   return (
      reverse(
         group_char.join(
            split(reverse(int_part))
         )
      ) + num[num.find(decimal_char):]
   ).replace(" %s" % group_char, "  ")


if __name__ == "__main__":
   # Testen welche Funktion schneller ist

   import time

   zahlen = (
      66,
      1,
      2,
      3.4,
      -5.678,
      612345,
      612345.555,
      987654321.067
   )

   begin = time.time()

   for i in range(10000):
      for zahl in zahlen:
         x = format_number_0a(zahl)

   print "0a:", time.time() - begin
   print

   begin = time.time()

   for i in range(10000):
      for zahl in zahlen:
         x = format_number_0b(zahl)

   print "0b:", time.time() - begin
   print

   begin = time.time()

   for i in range(10000):
      for zahl in zahlen:
         x = format_number_1(zahl)

   print "1:", time.time() - begin
   print


   begin = time.time()

   for i in range(10000):
      for zahl in zahlen:
         x = format_number_1b(zahl)

   print "1b:", time.time() - begin
   print

   begin = time.time()

   for i in range(10000):
      for zahl in zahlen:
         x = format_number_2(zahl)

   print "2:", time.time() - begin
   print

Code: Alles auswählen

0a: 0.921999931335

0b: 1.31200003624

1: 2.4849998951

1b: 1.32800006866

2: 1.57800006866
Ein guter kompromiss (wenn Python >v2.3) ist wohl die 1b Version... Dort hab ich die reverse() Funktion von Milan eingebaut...

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
BlackJack

jens hat geschrieben:

Code: Alles auswählen

   def reverse(string):
      # ersatz für string[::-1] welches erst ab v2.3 gibt :(
      list = re.findall(".",string)
      list.reverse()
      return "".join(list)
`list` ist hier ein ganz schlechter Name, weil man genau hier das eingebaute `list()` benutzen kann, um ohne den regulären Ausdruck auszukommen:

Code: Alles auswählen

In [6]: list("hallo")
Out[6]: ['h', 'a', 'l', 'l', 'o']
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Hier mal ein Test, wie schnell oder langsam die unterschiedlichen reverse() Geschichten sind:

Code: Alles auswählen

import time, re

def reverse0(string):
    l = list( string )
    l.reverse()
    return "".join(l)

def reverse1(s):
    l = map(None, s)
    l.reverse()
    return ('').join(l)

def reverse2(string):
    list = re.findall(".",string)
    list.reverse()
    return "".join(list)

def reverse3(s):
    return s[::-1]


TestString = "1234567890abcdefghijklmnopqrstuvwxyz"
loops = 500000

begin = time.time()
for i in xrange(loops): reverse0( TestString )
print "reverse0: %0.3f" % (time.time()-begin)

begin = time.time()
for i in xrange(loops): reverse1( TestString )
print "reverse1: %0.3f" % (time.time()-begin)

begin = time.time()
for i in xrange(loops): reverse2( TestString )
print "reverse2: %0.3f" % (time.time()-begin)

begin = time.time()
for i in xrange(loops): reverse3( TestString )
print "reverse3: %0.3f" % (time.time()-begin)

Code: Alles auswählen

reverse0: 2.594
reverse1: 2.500
reverse2: 12.953
reverse3: 0.609

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
HarryH
User
Beiträge: 266
Registriert: Freitag 23. Mai 2003, 09:08
Wohnort: Deutschland

Hi,

Der in den obigen Beispielen verwendete regex muss noch folgendemaßen abgeändert werden:

Code: Alles auswählen

regex = re.compile("^ *\d*\D\d{1,%s}|\d{1,%s}[ -]*" % (groupRange, groupRange))
Ich hatte nämlich ganz vergessen das es auch negative Zahlen gibt :oops:
Jetzt werden auch diese korrekt wiedergegeben.
Gruß, Harry
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Mir ist da gerade eine Idee gekommen...
Man könnte sich die umkehrung ersparen, wenn man die Zahl vor der RE auffüllt, dann durch RE die tausenderpunkte einfügen läßt und danach, die Aufgefüllten Zeichen wieder abschneidet.

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
cime
User
Beiträge: 152
Registriert: Dienstag 24. Mai 2005, 15:49

cime hat geschrieben:darf ich ma fragen warum das hier so kompliziert gemacht wird?

er will doch nur eine einfache formatierung, die man auch selber schreiben kann, ohne irgendwelche module, oder hab ich das falsch verstanden?

Code: Alles auswählen

#format_number.py

def format_number(number):
    hinter_komma=str(number%1)[2:]
    if not hinter_komma:
        hinter_komma="00"
    elif len(hinter_komma)==1:
        hinter_komma+="0"
    else:
        hinter_komma=hinter_komma[0:2]
    string=","+hinter_komma
    number=int(number)
    x=1
    while 1000**x<=number:
        string="."+str(number%(1000**x))[0:3]+string
        x+=1
    string=str(number/(1000**(x-1)))+string
    return string

print format_number(input("Zahl: "))
das hier macht exakt das, was er haben will, oder?
Hi,

wollt ma fragen, warum ihr meinen code einfach ma so ignoriert. Er hat schließlich ein paar Vorteile:
1. er nutzt keine nicht automatisch schon importierten Funktionen (/Module)
2. er ist mit abstand am schnellsten (sieher unten)

Hier ist er nochmal im Vergleich mit den anderen:

Code: Alles auswählen

# -*- coding: cp1252 -*-
#format_number.py

def format_number_0(number):
    if number<0:
         vorzeichen="-"
         number=-number
    else:
        vorzeichen=""
    hinter_komma=str(number%1)[2:]
    if not hinter_komma:
        hinter_komma="00"
    elif len(hinter_komma)==1:
        hinter_komma+="0"
    else:
        hinter_komma=hinter_komma[0:2]
    string=","+hinter_komma
    number=int(number)
    x=1
    while 1000**x<=number:
        string="."+str(number%(1000**x))[0:3]+string
        x+=1
    string=vorzeichen+str(number/(1000**(x-1)))+string
    return string

#----------------------------------------------------------------------

import re 

#---------------------------------------------------------------------- 
def format_number_1( 
   number, 
   format = "%0.2f", 
   decimal_char = ",", 
   group_char = ".", 
   group_range = 3 
): 
   """
   Nach einer Idee von Voges, HarryH und Jens. 
   http://www.python-forum.de/viewtopic.php?t=371 
   """
    
   def reverse(string): 
      # ersatz für string[::-1] welches erst ab v2.3 gibt :( 
      list = re.findall(".",string) 
      list.reverse() 
      return "".join(list) 
    
   regex = re.compile( 
      "^ *\d*\D\d{1,%s}|\d{1,%s} *" % (group_range, group_range) 
   ) 
    
   return reverse( 
      group_char.join( 
         regex.findall( 
            reverse( (format % number).replace( 
               ".", decimal_char) 
            ) 
         ) 
      ) 
   ) 


#---------------------------------------------------------------------- 
def format_number_2( 
   number, 
   format = "%0.2f", 
   decimal_char = ",", 
   group_char = ".", 
   group_range = 3 
): 
   """
   Nach einer Idee von Milan. 
   http://www.python-forum.de/viewtopic.php?t=371 
    """

   def split(s, size = group_range): 
      return map(lambda i: s[i:i + size], xrange(0, len(s), size)) 

   def reverse(s): 
      l = map(None, s) 
      l.reverse() 
      return ('').join(l) 

   num = (format % number).replace('.', decimal_char) 
   int_part = num[:num.find(decimal_char)] 
   return ( 
      reverse( 
         group_char.join( 
            split(reverse(int_part)) 
         ) 
      ) + num[num.find(decimal_char):] 
   ).replace(" %s" % group_char, "  ") 
    

if __name__ == "__main__": 
    # Testen welche Funktion schneller ist 

    import time 

    zahlen = ( 
      66, 
      1, 
      2, 
      3.4, 
      -5.678, 
      612345, 
      612345.555, 
      987654321.067 
    )
    for x in range(10):
        begin = time.time()

        for i in range(10000): 
          for zahl in zahlen: 
             x = format_number_0(zahl) 

        print "0:", time.time() - begin 
        print 

        begin = time.time() 

        for i in range(10000): 
          for zahl in zahlen: 
             x = format_number_1(zahl) 
              
        print "1:", time.time() - begin 
        print

        begin = time.time() 

        for i in range(10000): 
          for zahl in zahlen: 
             x = format_number_2(zahl) 
              
        print "2:", time.time() - begin 
        print 
Ergebnis:

Code: Alles auswählen

0: 0.828000068665

1: 3.93799996376

2: 2.9849998951

0: 0.81299996376

1: 4.17199993134

2: 2.70299983025

0: 0.844000101089

1: 4.0

2: 2.7349998951

0: 0.891000032425

1: 4.09299993515

2: 2.68799996376

0: 0.827999830246

1: 4.15600013733

2: 3.17200016975

0: 0.875

1: 4.0

2: 2.78099989891

0: 0.844000101089

1: 3.96900010109

2: 2.81299996376

0: 0.844000101089

1: 4.01499986649

2: 2.79699993134

0: 0.844000101089

1: 3.95300006866

2: 2.8900001049

0: 0.875

1: 4.53200006485

2: 2.73500013351
mawe
Python-Forum Veteran
Beiträge: 1209
Registriert: Montag 29. September 2003, 17:18
Wohnort: Purkersdorf (bei Wien [Austria])

Hi!

Ich werf auch mal eine Version ins Rennen ;

Code: Alles auswählen

def commify(number, comma=",", thousand="."):
    n = str(number).split(comma)
    n[0] = list(str(n[0]))[::-1]
    n[0] = thousand.join(
            ["".join(n[0][i:i+3][::-1]) for i in     
             range(0,len(n[0]),3)][::-1])
    return comma.join(n)

print commify(100000000)
print commify(1000.58,comma=".",thousand=",")
print commify("2,45")
print commify(1234567)
print commify("22343435455423423,2344324234")
Wie's mit der Performance aussieht, weiß ich nicht (ist das überhaupt wichtig?). Von den vielen [::-1] wird mir zwar schlecht, dafür kann man sich die Zeichen für Komma und Tausendertrennung aussuchen (es soll ja Leute geben, bei denen das Komma ein Punkt ist ;)).

Gruß, mawe
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

mawe hat geschrieben:Wie's mit der Performance aussieht, weiß ich nicht (ist das überhaupt wichtig?).
Kommt IMHO drauf an... Wenn man eine große Tabelle "umformen" will, ist es schon nicht schlecht, das es recht schnell geht...

Der größte Knackpunkt ist wohl, wenn Python's [::-1] zum umdrehen nicht vorliegt!

Aber wie schon geschrieben, was ist mit der Idee den Zahl-String auf zu füllen, das es gerade teilbar durch drei ist? ich hab gerade andere Sachen um das mal zu testen...

@cime: Sorry, hatte deinen Code glatt übersehen... Mir scheint es IMHO nur sehr lang ;)

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
mawe
Python-Forum Veteran
Beiträge: 1209
Registriert: Montag 29. September 2003, 17:18
Wohnort: Purkersdorf (bei Wien [Austria])

jens, ich weiß nicht ob ich verstanden habe was Du meinst, aber ich hab mal das zusammengestoppelt:

Code: Alles auswählen

def commify(number, comma=",", thousand="."):
    n = str(number).split(comma)
    x = len(n[0]) % 3
    n[0] = "%s%s" % ("0" * (3-x), n[0])
    n[0] = thousand.join([n[0][i:i+3] 
              for i in range(0,len(n[0]),3)]).lstrip("0%s" % thousand)
    return comma.join(n)
Sieht auch recht performant aus :)
Benutzeravatar
gerold
Python-Forum Veteran
Beiträge: 5555
Registriert: Samstag 28. Februar 2004, 22:04
Wohnort: Oberhofen im Inntal (Tirol)
Kontaktdaten:

cime hat geschrieben: wollt ma fragen, warum ihr meinen code einfach ma so ignoriert. Er hat schließlich ein paar Vorteile:
1. er nutzt keine nicht automatisch schon importierten Funktionen (/Module)
2. er ist mit abstand am schnellsten (sieher unten)
Hi crime!

Ich habe deinen Code deshalb nicht getestet, da es mir wichtig ist, mindestens das Format, das Dezimaltrennzeichen und das Zeichen für die Gruppierung übergeben zu können. Das Einbauen dieser Variablen schien mir bei deinem Code zu kompliert.

Das Format ist wichtig, um auch einfache Listen realisieren zu können. Z.B. mit %15.2f. Oder auch die Rundung besser im Griff zu haben.

lg
Gerold
:-)
http://halvar.at | Kleiner Bascom AVR Kurs
Wissen hat eine wunderbare Eigenschaft: Es verdoppelt sich, wenn man es teilt.
mawe
Python-Forum Veteran
Beiträge: 1209
Registriert: Montag 29. September 2003, 17:18
Wohnort: Purkersdorf (bei Wien [Austria])

gerold hat geschrieben: da es mir wichtig ist, mindestens das Format, das Dezimaltrennzeichen und das Zeichen für die Gruppierung übergeben zu können.
Formatieren kannst Du's doch auch bevor die Zahl an die Funktion übergeben wird.
HarryH
User
Beiträge: 266
Registriert: Freitag 23. Mai 2003, 09:08
Wohnort: Deutschland

Hi,

Habe noch eine Lösung gefunden. Sie ist der von cime ähnlich und etwas langsamer aber ca. 20% schneller als die regex-Lösung. Dafür kann man defChar, groupChar, groupRange und das Ausgabeformat übergeben.
Das Format gilt allerdings nur für die Nachkommastellen. Möchte man den ganzen Wert formatiert darstellen, muss man die Rückgabe der Funktion nochmals formatieren (z.B. mit %20s").
Außerdem ist sie auch für Pythonversionen < python 2.4 einsetzbar.
So sieht die Lösung aus:

Code: Alles auswählen

def __formatter(number, format = "%.2f", decChar = ",", groupChar = ".", groupRange = 3):
    """
    Convert to required format
    number =      number to convert
    format =      python string formatting (%),but only for the decimals
    decChar =     decimal char for the converted format
    groupChar =   group char for the converted format
    groupRange =  group range for the converted format

    For example:
    __formatter(1234567890.987, "%.2f", ",", ".", 3)
    ==> 1.234.567.890,99

    """
    if abs(number) < 1:
        return (format % (number)).replace(".", decChar)
    else:
        base = int(abs(number))
        s = (format % (abs(number) % 1))[2:]
        s = s and decChar + s or s
        while base:
            s = groupChar + str(base)[-groupRange:] + s
            base = int(base / 10**groupRange)
        return number < 0 and "-" + s[1:] or s[1:]
Den regEx der vorherigen Lösungen habe ich auch nochmals überarbeitet. Zahlen kleiner als Tausend wurden bei z.B. %20.2f nicht korrekt dargestellt. Bei negativen Zahlen größer als 1000 wurde das Minuszeichen entfernt.
Das ist der korrigierte regEx:

Code: Alles auswählen

re.compile("^ *\d*\D\d{1,%s}[ -]*|\d{1,%s}[ -]*" % (3, 3))
Ein weiteres Problem der regEx-Lösung ist, das die Formatierung nicht richtig dargestellt wird. Z.B. wird bei "%20.2f" jede Zahl pro Tausenderpotenz um ein Zeichen (nämlich das Gruppierungszeichen) länger. Das Ergebnis sieht dann folgendermaßen aus:

Code: Alles auswählen

             -0,234
              66,090
               1,000
               2,000
               3,400
              -5,678
          612.345,000
          612.345,555
      9.876.543.210,067
Um dieses Problem zu beheben müßte man den Code noch erweitern. Dadurch wird er aber noch langsamer.

Am besten wäre es natürlich wenn man über den Formatierungsoperator (%) Zahlen auch mit Gruppierungszeichen darstellen könnte. Eine gute Anregung an die Python-Programmierer.
Gruß, Harry
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

HarryH hat geschrieben:Eine gute Anregung an die Python-Programmierer.
Ich habe es schon mal eingetragen: http://www.pythonwiki.de/PythonWunschliste

Wie man aus den http://www.pythonwiki.de/Aktuelle%C3%84nderungen entnehmen kann ist die Seite allerdings gelöscht worden :evil:

Man kann sich aber noch die die alte Version anschauen mit: http://www.pythonwiki.de/PythonWunschli ... iff&rev2=8

Weiß jemand was da passiert ist???

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Leonidas
Python-Forum Veteran
Beiträge: 16025
Registriert: Freitag 20. Juni 2003, 16:30
Kontaktdaten:

jens hat geschrieben:Weiß jemand was da passiert ist???
Ja, ich vermute mal, dass es irgendein Fehler in MoinMoin ist, denn die Seite kann nicht mehr wiederhergestellt werden und auch nicht wieder angelegt werden. Ich habe mal dem Admin geschrieben, aber noch keine Antwort bekommen (es ist ja Wochenende).
My god, it's full of CARs! | Leonidasvoice vs (former) Modvoice
joe

jens hat geschrieben:Weiß jemand was da passiert ist???
Ich nehme an, gelöscht wegen "thema verfehlt". Bei wünschen für python 3000 geht es ja um sachen, die vorher nicht realisierbar sind, weil sie die rückwärtskompatibilität gefährden. Und auf der gelöschten seite war ja nichts (außer vielleicht der print-geschichte), was nicht auch in Version 2.5 oder 2.99 aufgenommen werden könnte. Oder wieso wolltest du den zahlenformatierer erst in der 3.0-version?
joe
Benutzeravatar
jens
Python-Forum Veteran
Beiträge: 8502
Registriert: Dienstag 10. August 2004, 09:40
Wohnort: duisburg
Kontaktdaten:

Also ich habe die Seite ehr als allgemeine Wunschliste verstanden und nicht unbedingt eine zweite PEP 3000 ;)

GitHub | Open HUB | Xing | Linked in
Bitcoins to: 1JEgSQepxGjdprNedC9tXQWLpS424AL8cd
Antworten