Nach jeder dritten Ziffer ein Komma machen

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
mxrxtzzzz
User
Beiträge: 6
Registriert: Samstag 3. August 2019, 21:54

Hallo ich bin ein Neuling was Python angeht und deswegen stelle ich diese Frage
Wie kann ich nach jder dritten Ziffer ein Komma setzen
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

print(“,”)
Benutzeravatar
snafu
User
Beiträge: 6866
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

@mxrxtzzzz: Geht es um Tausendertrennzeichen? Das kann Python automatisch für dich übernehmen, wenn man ein Komma als Format Specifier mitgibt. Falls du das für Geldbeträge nutzen willst, kannst du noch angeben, dass du z.B. immer 2 Nachkommastellen haben willst:

Code: Alles auswählen

print('The amount is ${:,.2f}'.format(12345678.90))
Benutzeravatar
__blackjack__
User
Beiträge: 14047
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Falls es um Geldberträge geht, kann man auch die Kanone für den Spatz auffahren – `babel`:

Code: Alles auswählen

In [66]: from babel.numbers import format_currency

In [67]: print(format_currency('12345678.90', 'USD', locale='en_US'))
$12,345,678.90

In [68]: print(format_currency('12345678.90', 'USD', locale='de_DE'))
12.345.678,90 $
Geht auch ohne Währung, dann mit `format_decimal()`.
“Vir, intelligence has nothing to do with politics!” — Londo Mollari
Benutzeravatar
snafu
User
Beiträge: 6866
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Ansonsten bringt Python noch die currency()-Funktion aus dem locale-Modul mit. Dann muss man aber das (kurzzeitige) Umstellen der Locale-Einstellungen selbst übernehmen, damit es funktioniert. Lassen wir vielleicht erstmal den TE zu Wort kommen, bevor das zu sehr in eine Richtung geht, die vielleicht gar nicht relevant für ihn ist.
mxrxtzzzz
User
Beiträge: 6
Registriert: Samstag 3. August 2019, 21:54

Danke für die Antworten, aber ich rechne nicht mit Geldbeträgen, sondern mit ganz normalen Zahlen.
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

Du musst schon deutlich weiter ausholen, damit man dir helfen kann. Was willst du machen, wie sieht dein Code aus, und so weiter. Hier mit launigen ein-Satz-fragen zum Ziel kommen zu wollen wird nix.
mxrxtzzzz
User
Beiträge: 6
Registriert: Samstag 3. August 2019, 21:54

Ich habe ein Liste von Zahlen zB. 252567880834 die ich dann mit dem Code verändern will, sodass es so ausschauen soll: 252,567,880,834
Mehr hab ich nicht an Code
__deets__
User
Beiträge: 14545
Registriert: Mittwoch 14. Oktober 2015, 14:29

Das ist kein Code. Das ist nur eine Aufgabe. Und eigentlich hat Snafu dir dafür Hilfestellung gegeben. Das sind dann doch einfach 1000er trenn Zeichen.
mxrxtzzzz
User
Beiträge: 6
Registriert: Samstag 3. August 2019, 21:54

Und wenn ich eine Strich machen will oder ein Leerzeichen?
Sirius3
User
Beiträge: 18270
Registriert: Sonntag 21. Oktober 2012, 17:20

Was hast Du Dir selbst schon für Gedanken dazu gemacht?
Benutzeravatar
snafu
User
Beiträge: 6866
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Man könnte auch eine rein mathematische Lösung nehmen, aber ich würde hier einfach eine Funktion basteln, die auf der String-Repräsentation der Zahl beruht. Die arbeitet dann mit einem beliebigen Trenner für die Gruppierung. Dank der extrem umfangreichen Infos des TEs ist hier nicht klar ob immer ganze Gruppen herauskommen (also Anzahl der Ziffern ein Vielfaches von 3) oder ob man auch mit einer Gruppe von einem oder zwei Elementen rechnen muss und was dann passieren soll. Ich bin hier mal von letzterem ausgegangen und setze gemäß der üblichen Regeln für die Gruppierung von Zahlen die unvollständige Gruppe nach links (1234567 -> 1,234,567). Die Unterstützung von Floats habe ich weggelassen. Hier mein Code:

Code: Alles auswählen

from itertools import zip_longest

def grouped_int(number, sep=','):
    string = str(int(number))
    indices = [0, *range(len(string) % 3 or 3, len(string), 3)]
    slices = zip_longest(indices, indices[1:])
    return sep.join(string[start:stop] for start, stop in slices)

def test():
    numbers = [1, 12, 123, 1234, 12345, 123456, 1234567, -1, -12345]
    for n in numbers:
        grouped = grouped_int(n, ',')
        assert grouped == format(n, ',')
        print(grouped)

if __name__ == '__main__':
    test()
Sirius3
User
Beiträge: 18270
Registriert: Sonntag 21. Oktober 2012, 17:20

@snafu: das ist etwas unschön

Code: Alles auswählen

>>> grouped_int(-123)
'-,123'
Benutzeravatar
snafu
User
Beiträge: 6866
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Hier der verbesserte Umgang mit negativen Zahlen, kann nun auch Dezimalzahlen formatieren:

Code: Alles auswählen

from itertools import zip_longest

def get_grouped(number, sep=',', grouplen=3):
    string = str(number)
    is_negative = string.startswith('-')
    int_digits = str(int(number)).lstrip('-')
    first_sep_index = (len(int_digits) % grouplen or grouplen) + is_negative
    stop_index = len(int_digits) + is_negative
    slices = [0, *range(first_sep_index, stop_index, grouplen)]
    return sep.join(
        string[start:stop] for start, stop in zip_longest(slices, slices[1:])
    )

def _print_asserted(result, expected):
    assert result == expected, f'{result} != {expected}'
    print(result)

def test():
    numbers = [1, 12, 123, 1234, 12345, 123456, 1234567, -1, -123, -12345,
               0.5, 0.12345, 12345678.90, -0.5, -0.12345, -12345678.90]
    for n in numbers:
        _print_asserted(get_grouped(n), format(n, ','))
    _print_asserted(get_grouped(1234567890, '-', 4), '12-3456-7890')

if __name__ == '__main__':
    test()
Benutzeravatar
snafu
User
Beiträge: 6866
Registriert: Donnerstag 21. Februar 2008, 17:31
Wohnort: Gelsenkirchen

Hier nochmal etwas Refactoring. Das Gruppieren innerhalb einer Zeichenkette ist jetzt der allgemeine Fall und bei Zahlen ist es der spezielle Fall.

Code: Alles auswählen

from itertools import zip_longest
from numbers import Number

def grouped_string(s, sep=' ', group_size=3, start_index=0, stop_index=None):
    if stop_index is None:
        stop_index = len(s)
    offset = (stop_index - start_index) % group_size
    first_sep_index = (offset or group_size) + start_index
    indices = [0, *range(first_sep_index, stop_index, group_size)]
    return sep.join(
        s[start:stop] for start, stop in zip_longest(indices, indices[1:])
    )

def grouped_number(num, sep=',', group_size=3):
    string = str(num)
    is_signed = string.startswith(('+', '-'))
    int_digits = str(int(num)).lstrip('+-')
    return grouped_string(
        string, sep, group_size,
        int(is_signed), len(int_digits) + int(is_signed)
    )

def get_grouped(obj, sep=',', group_size=3):
    if isinstance(obj, Number):
        return grouped_number(obj, sep, group_size)
    return grouped_string(str(obj), sep, group_size)

def _print_asserted(result, expected):
    assert result == expected, f'{result} != {expected}'
    print(result)

def test():
    numbers = [1, 12, 123, 1234, 12345, 123456, 1234567, -1, -123, -12345,
               0.5, 0.12345, 12345678.90, -0.5, -0.12345, -12345678.90]
    for n in numbers:
        _print_asserted(get_grouped(n), format(n, ','))
    _print_asserted(get_grouped(1234567890, '-', 4), '12-3456-7890')
    _print_asserted(get_grouped('ABCDEFGHIJKL', ' ', 5), 'AB CDEFG HIJKL')

if __name__ == '__main__':
    test()
mxrxtzzzz
User
Beiträge: 6
Registriert: Samstag 3. August 2019, 21:54

Man könnte auch eine rein mathematische Lösung nehmen, aber ich würde hier einfach eine Funktion basteln, die auf der String-Repräsentation der Zahl beruht. Die arbeitet dann mit einem beliebigen Trenner für die Gruppierung. Dank der extrem umfangreichen Infos des TEs ist hier nicht klar ob immer ganze Gruppen herauskommen (also Anzahl der Ziffern ein Vielfaches von 3) oder ob man auch mit einer Gruppe von einem oder zwei Elementen rechnen muss und was dann passieren soll. Ich bin hier mal von letzterem ausgegangen und setze gemäß der üblichen Regeln für die Gruppierung von Zahlen die unvollständige Gruppe nach links (1234567 -> 1,234,567). Die Unterstützung von Floats habe ich weggelassen
Es sind immer 9 Ziffern also kommen immer 3 dreier Gruppen raus ;-)
Benutzeravatar
noisefloor
User
Beiträge: 4191
Registriert: Mittwoch 17. Oktober 2007, 21:40
Wohnort: WW
Kontaktdaten:

Hallo,

@mxrxtzzz: was ist denn der Hintergrund? Ist das ein Projekt von dir? Oder eine Hausaufgabe von Schule oder Uni? Wenn ja -> sag' das bitte explizit und sag', was du schon weißt bzw. kann.
Wenn's eine Hausaufgabe ist würde ich auf Schleife und Modulo-Division als Ziel tippen...

Gruß, noisefloor
mxrxtzzzz
User
Beiträge: 6
Registriert: Samstag 3. August 2019, 21:54

Es ist ein Projekt von mir, nicht von der Schule
Es ist ein Sudoku-Löser den ich mit Hilfe von Tutorials gemacht habe(in Vs Code).
Jetzt schaut das im Terminal zB so aus(kein echtes Sudoku):
235829477
467283745
628837483
293746510
471937393
528292637
828376319
561947732
628265395

Ich möchte es aber so

235 | 829 | 477
467 | 283 | 745
628 | 837 | 483
------------------------
293 | 746 | 510
471 | 937 | 393
528 | 292 | 637
------------------------
828 | 376 | 319
561 | 947 | 732
628 | 265 | 395
Sirius3
User
Beiträge: 18270
Registriert: Sonntag 21. Oktober 2012, 17:20

@mxrxtzzzz: dazu müßte man wissen, in welcher Datenstruktur Du die Zahlen hast.

Wahrscheinlich eine Liste. Manchmal ist das explizite ausschreiben doch das lesbarste:

Code: Alles auswählen

def print_line(line):
    print(f"{line[0]}{line[1]}{line[2]}|{line[3]}{line[4]}{line[5]}|{line[6]}{line[7]}{line[8]}")

def print_sudoku(sudoku):
    print_line(sudoku[0])
    print_line(sudoku[1])
    print_line(sudoku[2])
    print('-' * 11)
    print_line(sudoku[3])
    print_line(sudoku[4])
    print_line(sudoku[5])
    print('-' * 11)
    print_line(sudoku[6])
    print_line(sudoku[7])
    print_line(sudoku[8])


sudoku = [
    [2, 3, 5, 8, 2, 9, 4, 7, 7],
    [4, 6, 7, 2, 8, 3, 7, 4, 5],
    [6, 2, 8, 8, 3, 7, 4, 8, 3],
    [2, 9, 3, 7, 4, 6, 5, 1, 0],
    [4, 7, 1, 9, 3, 7, 3, 9, 3],
    [5, 2, 8, 2, 9, 2, 6, 3, 7],
    [8, 2, 8, 3, 7, 6, 3, 1, 9],
    [5, 6, 1, 9, 4, 7, 7, 3, 2],
    [6, 2, 8, 2, 6, 5, 3, 9, 5],
]
print_sudoku(sudoku)
Benutzeravatar
noisefloor
User
Beiträge: 4191
Registriert: Mittwoch 17. Oktober 2007, 21:40
Wohnort: WW
Kontaktdaten:

Hallo,

wenn du 3er Gruppen einsetzen willst, halte ich den Lösunganssatz generell für sehr fragwürdig. Ein Sudoko ist ja auch eine 9x9 Feld mit 1-stelligen Zahlen pro Feld und kein 3x3 Feld mit 3-stelligen Zahlen...

Gruß, noisefloor
Antworten