Integer mit Tausender-Trennzeichen versehen?

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
api
User
Beiträge: 181
Registriert: Donnerstag 7. August 2008, 21:23

Hallo zusammen,

ich habe das Problem, dass ich einen Integer-Wert (zB 43908132) mit Tausender-Trennzeichen ausgeben möchte => also in der Form (43.908.132).

Gibt es da irgendeine Funktion für? Behandelt das irgendein Modul bereits?

Kann mir da jemand einen Tipp geben, wie ich das am besten anfange?

CU,
API
Benutzeravatar
BlackVivi
User
Beiträge: 762
Registriert: Samstag 9. Dezember 2006, 14:29
Kontaktdaten:

Ist ja nur eine Darstellungssache, also muss es am Ende ein String sein, ganz klar. Und wenn man sich das anschaut... bei jedem dritten Zeichen muss ja'n . also vielleicht... Auseinanderbauen und bei jeden dritten neben dem String noch'n . dahinter... Nur grobe Überlegungen. Würde es jetzt so programmieren, könnte das auch machen... aber bringt dir ja nix :3
api
User
Beiträge: 181
Registriert: Donnerstag 7. August 2008, 21:23

Hi BlackVivi,

ja klar - du hast Recht. Natürlich könnte ich das als String behandeln, den zerlegen und mit Punkten wieder zusammenbasteln. Aber ich kann mir irgendwie nicht vorstellen, dass es dafür keine Funktion gibt. So wie man auch mit print Formate mitgeben kann...

Wahrscheinlich verbringe ich am Ende mehr Zeit mit der Suche nach solch einer Funktion als ich für das Script dazu benötigt hätte.. :D

CU,
API
audax
User
Beiträge: 830
Registriert: Mittwoch 19. Dezember 2007, 10:38

Code: Alles auswählen

from itertools import cycle, izip

def format_int(i):
    return ''.join(reversed(
        sum(
            izip(
                reversed(str(i)),
                cycle(['', '', '.'])),
            tuple()
        )))
assert format_int(10000000000) == '10.000.000.000'
(Ja, das ist wirklich die erste Lösung, die mir in den Sinn kam :o)

€dit:
Import vergessen
€dit²:
Nächsten Import vergessen.
Zuletzt geändert von audax am Donnerstag 7. August 2008, 22:59, insgesamt 2-mal geändert.
Benutzeravatar
BlackVivi
User
Beiträge: 762
Registriert: Samstag 9. Dezember 2006, 14:29
Kontaktdaten:

Code: Alles auswählen

def seperate_number(nr):
    seperated_nr = ""
    for enu, part_nr in enumerate(str(nr)[::-1]):
        if (enu + 1) % 3 == 0 and enu != len(str(nr)) - 1:
            seperated_nr += part_nr + "."
        else:
            seperated_nr += part_nr
    return seperated_nr[::-1]
in 5 Minuten geschrieben und total unverständlich und bestimmt kommt in 5 Minuten BlackJack oder Leonidas mit einer 10000mal besseren Lösung oder sagt wie doof meine ist, also wie immer ;P
audax
User
Beiträge: 830
Registriert: Mittwoch 19. Dezember 2007, 10:38

BlackVivi hat geschrieben:

Code: Alles auswählen

def seperate_number(nr):
    seperated_nr = ""
    for enu, part_nr in enumerate(str(nr)[::-1]):
        if (enu + 1) % 3 == 0 and enu != len(str(nr)) - 1:
            seperated_nr += part_nr + "."
        else:
            seperated_nr += part_nr
    return seperated_nr[::-1]
in 5 Minuten geschrieben und total unverständlich und bestimmt kommt in 5 Minuten BlackJack oder Leonidas mit einer 10000mal besseren Lösung oder sagt wie doof meine ist, also wie immer ;P
Ich persönlich finde reversed() besser als [::-1] aber das ist Geschmackssache, allerdings solltest du so dinge wie "len(str(nr)) - 1" einfach einmal am Anfang berechnen und gut ist, ebenso würde ich eher mit einer Liste von einzelnen Zeichen arbeiten und die zum Schluss joinen, weil Strings leider immutable sind. Außerdem würde ich einfach in der Schleife einmal "idx = enu + 1" setzen und mir das leidige +1 und -1 sparen, dann sähe der Schluss z.B. so aus:

Code: Alles auswählen

    seperate_number.append(part_nr)
    if not idx % 3 and idx != length:
        seperate_number.append('.')
return ''.join(seperate_number)
Benutzeravatar
BlackVivi
User
Beiträge: 762
Registriert: Samstag 9. Dezember 2006, 14:29
Kontaktdaten:

Wie gesagt, is'ne gehackte Lösung und das mit Strings arbeiten beim zusammenführen war mir auch bewusst... würds aber erst anders machen, wenn's tatsächlich ein Probleme wäre in'r Geschwindigkeit. Das mit dem idx + 1, ... hast wohl recht, wie gesagt Oo Ist total hackig.... Würde es wohl im Produktivfall so schreiben:

Code: Alles auswählen

def seperate_number(nr):
    nr = list(str(nr)[::-1])
    seperated_nr = list()
    length = len(nr)
    for enu, part_nr in enumerate(nr):
        enu += 1
        if enu % 3 == 0 and enu != length:
            seperated_nr.append("." + part_nr)
        else:
            seperated_nr.append(part_nr)
    return "".join(seperated_nr[::-1])
Auch nich perfekt,... aber ich kann sowas eh nich so gut =/
audax
User
Beiträge: 830
Registriert: Mittwoch 19. Dezember 2007, 10:38

Ach Mensch...meins hat dafür nen Bug ;)
Benutzeravatar
BlackVivi
User
Beiträge: 762
Registriert: Samstag 9. Dezember 2006, 14:29
Kontaktdaten:

audax hat geschrieben:Ach Mensch...meins hat dafür nen Bug ;)

Code: Alles auswählen

>>> format_int(2000)
'2.000'
>>> format_int(200)
'.200'
;PPP
Benutzeravatar
numerix
User
Beiträge: 2696
Registriert: Montag 11. Juni 2007, 15:09

Man hätte auch einfach diesen Thread lesen können:

http://www.python-forum.de/topic-13745. ... enderpunkt
Pekh
User
Beiträge: 482
Registriert: Donnerstag 22. Mai 2008, 09:09

api hat geschrieben: ja klar - du hast Recht. Natürlich könnte ich das als String behandeln, den zerlegen und mit Punkten wieder zusammenbasteln. Aber ich kann mir irgendwie nicht vorstellen, dass es dafür keine Funktion gibt. So wie man auch mit print Formate mitgeben kann...
Das scheitert schon daran, daß im angelsächsischen Sprachraum Punkt und Komma genau andersherum verwendet werden. Wenn es denn eine entsprechende Funktion gäbe, würde sie also vermutlich etwas in der Art hier erzeugen:

Code: Alles auswählen

12,560,340.5
Sieht also eher schlecht aus :?
audax
User
Beiträge: 830
Registriert: Mittwoch 19. Dezember 2007, 10:38

Code: Alles auswählen

from itertools import cycle

def format_int(i, sep='.'):
    cyc = cycle(['', '', sep])
    s = str(i)
    last = len(s) - 1
    formatted = [(cyc.next() if idx != last else '') + char 
                 for idx, char in enumerate(reversed(s))]
    return ''.join(reversed(formatted))

assert format_int(10000000000) == '10.000.000.000'
assert format_int(100) == '100'
diesmal Bugfrei ;)

€dit:
Aber die locale-Funktion ist natürlich besser.
api
User
Beiträge: 181
Registriert: Donnerstag 7. August 2008, 21:23

Hallo zusammen,

das ist ja mehr als ich je erwartet habe.. :D

Nun habe ich eine Funktion (locale...) und 2 selbst (bzw. von BlackVivi & audax) geschriebene Funktionen.

Und ich muss schon sagen, dass das doch recht elegant aussieht.

Das hilft mir auf jeden Fall weiter... :D Danke Euch.

(Warum ich den Thread vorher nicht gesehen habe, weiss ich allerdings auch nicht)

CU,
API
Antworten