formatierte ausgabe von listen

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
4bit
User
Beiträge: 113
Registriert: Dienstag 5. Mai 2009, 11:27

Hallo,

ich stecke bei dem Versuch fest mehrere Listen nacheinander mit print auszugeben, sodaß deren unterschiedlich langen elemente genau untereinander stehen.

also etwa für jede liste:

Code: Alles auswählen

print len(liste)*"%5s" % liste
danke,

4b
Benutzeravatar
lutz.horn
User
Beiträge: 205
Registriert: Dienstag 8. November 2005, 12:57
Wohnort: Pforzheim

Code: Alles auswählen

l1 = ["foo", "baar", "baaaz"]
l2 = ["foooo", "bar", "baaz"]

# Länge des größen Eintrags.
m = max(len(i) for i in l1 + l2)

# Listen formatiert ausgeben
for l in (l1, l2):
    print " ".join("{0:{1}}".format(i, m) for i in l)
siehe http://docs.python.org/library/string.h ... matstrings

edit: in Python 3 print() verwenden
https://www.xing.com/go/invite/18513630.6a91d4
4bit
User
Beiträge: 113
Registriert: Dienstag 5. Mai 2009, 11:27

ah, ich benutze python 2.5, da gibt es die format methode noch nicht (mal updaten). ich habe die Seite, die du angegeben hast natürlich schon gesehen und gelesen, konnte aber damit nichts anfangen (vor allem, weil ich dachte, daß formatierte listen ausgeben ja nicht soo kompliziert sein kann)

hm. seltsam, daß print es einem nicht einfacher macht listen darzustellen.
gibt es vielleicht doch eine intuitivere art zum Beispiel Zeilen-Listen einer Matrix so nacheinander auszugeben, daß eine Tabelle entsteht?

Grüße,
Benutzeravatar
lutz.horn
User
Beiträge: 205
Registriert: Dienstag 8. November 2005, 12:57
Wohnort: Pforzheim

Ich glaube, dass mein Vorschlag recht pythonic ist, insbesondere durch die Verwendung von Generatoren. Aus der Sicht eines Python-Programmierers ist "pythonic" == "intuitiv" :)

Im Ernst: Was erscheint Dir an dieser Lösung unintuitiv?
https://www.xing.com/go/invite/18513630.6a91d4
4bit
User
Beiträge: 113
Registriert: Dienstag 5. Mai 2009, 11:27

naja, eine Lste ist ja schon ein Standardobjekt und Listeneinträge untereinander als Tabelle ausgeben auch irgendwie eine Standardaufgabe. Hätte gedacht man kommt aus ohne über die Elemente zu iterieren. Aber ist ja kein Problem.
Benutzeravatar
cofi
Python-Forum Veteran
Beiträge: 4432
Registriert: Sonntag 30. März 2008, 04:16
Wohnort: RGFybXN0YWR0

Nein, man muss ueber die Elemente gehen, da eine ``geprintete`` Liste die ``repr`` Darstellungen der Elemente hat.

Dein Ansatz ist fuer einen Python-Programmierer nicht intuitiv, weil sich das alles mit der Syntax von Format-Strings beisst, die eben die Argumente fuer sich aufnehmen und nicht als Template zur Darstellung einer Sequenz dienen ;)

(Vllt kann man das von Lutz auch noch besser gestalten, aber da fehlt mir grad die Muse und der Kaffee :roll:)
Benutzeravatar
HWK
User
Beiträge: 1295
Registriert: Mittwoch 7. Juni 2006, 20:44

4bit hat geschrieben:ah, ich benutze python 2.5, da gibt es die format methode noch nicht (mal updaten).
Geht aber auch mit Python < 2.6:

Code: Alles auswählen

>>> print '\n'.join((' '.join('%*s' % (m, x) for x in l)) for l in (l1, l2))
  foo  baar baaaz
foooo   bar  baaz
MfG
HWK
Benutzeravatar
mkesper
User
Beiträge: 919
Registriert: Montag 20. November 2006, 15:48
Wohnort: formerly known as mkallas
Kontaktdaten:

Ich hätte ja erwartet, dass jede Spalte eine eigene Länge hat.
Meine Lösung für Python < 2.6 und ohne jegliche List Comprehensions (meiner Meinung nach leichter zu lesen):

Code: Alles auswählen

results = list()
results.append(["foo", "baar", "baaaaaaaaaz"])
results.append(["foooo", "bar", "baaz"])
results.append(["fooooooooo", "bar", "baaaaaz"])

col_length = list()
for index, col in enumerate(results[0]):
    col_length.append(0)
    for row in results:
        if len(row[index]) > col_length[index]:
            col_length[index] = len(row[index])
print
for row in results:
    output = ""
    for index, col in enumerate(row):
        output = "| ".join((output, col.ljust(col_length[index] + 1)))
    output = "".join((output, "|"))    
    print output
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Also ich finde es mit LCs schöner:

Code: Alles auswählen

results = [
    ["foo", "baar", "baaaaaaaaaz"],
    ["foooo", "bar", "baaz"],
    ["fooooooooo", "bar", "baaaaaz"]
]

lengths = [max(map(len, x)) for x in zip(*results)]

for row in results:
    print "| ".join(col.ljust(length+1) for col, length in zip(row, lengths))
Wer gerne an den Namen spart, kann natürlich auch die ganze for-Schleife in eine LC packen ^^:

Code: Alles auswählen

print "\n".join("| ".join(v.ljust(l+1) for v, l in zip(r, ls))  for r in rs)
Natürlich sollten alle Zeilen gleich viele Elemente enthalten, sonst wird es problematisch.
Das Leben ist wie ein Tennisball.
derdon
User
Beiträge: 1316
Registriert: Freitag 24. Oktober 2008, 14:32

Um es noch schöner zu machen, kannste aus lengths eine GC machen und die Funktionen itertools.imap und itertools.izip verwenden.
EyDu
User
Beiträge: 4881
Registriert: Donnerstag 20. Juli 2006, 23:06
Wohnort: Berlin

Man kann keinen Generator für die Längen verwenden, da die Längen in der inneren for-Schleife verarbeitet werden. Mein Python 3 spart sich übrigens imap und izip. Aber wie man sieht, lege ich auch bei der älteren Version kein Werte auf den Import.
Das Leben ist wie ein Tennisball.
Antworten