36 Stimmen

Wie kann man eine Liste schöner drucken?

Dies ist vergleichbar mit Wie man eine Liste in Python "schön" ausdruckt aber ich würde die Liste gerne noch schöner ausdrucken - ohne die Klammern, Apostrophe und Kommas, und noch besser in Spalten.

foolist = ['exiv2-devel', 'mingw-libs', 'tcltk-demos', 'fcgi', 'netcdf', 
    'pdcurses-devel',     'msvcrt', 'gdal-grass', 'iconv', 'qgis-devel', 
    'qgis1.1', 'php_mapscript']

evenNicerPrint(foolist)

Erwünschtes Ergebnis:

exiv2-devel       msvcrt        
mingw-libs        gdal-grass    
tcltk-demos       iconv         
fcgi              qgis-devel    
netcdf            qgis1.1       
pdcurses-devel    php_mapscript 

Danke!

1 Stimmen

Erstens ist es keine gute Idee, dict als Variablennamen zu verwenden. Zweitens ist das, was Sie hier zu drucken versuchen, eine Liste, ein dict verwendet {} und :, um die Schlüssel und Werte zu trennen

3 Stimmen

-1: Im Titel der Frage steht "Liste" - eine komplette Verdoppelung. In der Frage steht "dict". Der Beispielcode ist eine Liste - eine komplette Verdoppelung. Möchten Sie, dass die Liste in ein Diktat umgewandelt und ausgedruckt wird? Wenn ja, ändern Sie die Frage, um zu beschreiben, was Sie vraiment wollen.

0 Stimmen

Ich habe die Beschreibung und den Beispielcode wie empfohlen korrigiert. Der Titel und die Beschreibung spiegeln jetzt mein Ziel wider. Vielen Dank für die Korrekturen.

34voto

Aman Punkte 42509

In dieser Antwort wird die gleiche Methode wie in der Antwort von @Aaron Digulla verwendet, allerdings mit einer etwas pythonischeren Syntax. Das könnte einige der obigen Antworten leichter verständlich machen.

>>> for a,b,c in zip(foolist[::3],foolist[1::3],foolist[2::3]):
>>>     print '{:<30}{:<30}{:<}'.format(a,b,c)

exiv2-devel                   mingw-libs                    tcltk-demos
fcgi                          netcdf                        pdcurses-devel
msvcrt                        gdal-grass                    iconv
qgis-devel                    qgis1.1                       php_mapscript

Dies kann leicht an eine beliebige Anzahl von Spalten oder variablen Spalten angepasst werden, was zu etwas wie der Antwort von @gnibbler führen würde. Die Abstände können an die Bildschirmbreite angepasst werden.


Aktualisierung: Erläuterung wie gewünscht.

Indizierung

foolist[::3] wählt jedes dritte Element von foolist . foolist[1::3] wählt jedes dritte Element aus, beginnend mit dem zweiten Element ('1', da Python eine Null-Indexierung verwendet).

In [2]: bar = [1,2,3,4,5,6,7,8,9]
In [3]: bar[::3]
Out[3]: [1, 4, 7]

zip

Das Zippen von Listen (oder anderen Iterablen) erzeugt Tupel aus den Elementen der Listen. Zum Beispiel:

In [5]: zip([1,2,3],['a','b','c'],['x','y','z'])
Out[5]: [(1, 'a', 'x'), (2, 'b', 'y'), (3, 'c', 'z')]

zusammen

Setzt man diese Ideen zusammen, erhält man unsere Lösung:

for a,b,c in zip(foolist[::3],foolist[1::3],foolist[2::3]):

Hier erzeugen wir zunächst drei "Scheiben" von foolist , jeweils indiziert durch jedes Drittel-Element und um eins versetzt. Einzeln enthalten sie jeweils nur ein Drittel der Liste. Wenn wir nun diese Slices zippen und iterieren, erhalten wir bei jeder Iteration drei Elemente von foolist .

Das ist es, was wir wollten:

In [11]: for a,b,c in zip(foolist[::3],foolist[1::3],foolist[2::3]):
   ....:      print a,b,c                           
Out[11]: exiv2-devel mingw-libs tcltk-demos
         fcgi netcdf pdcurses-devel
        [etc]

Anstelle von:

In [12]: for a in foolist: 
   ....:     print a
Out[12]: exiv2-devel
         mingw-libs
         [etc]

0 Stimmen

Können Sie bitte näher erläutern, was in zip(foolist...) passiert?

0 Stimmen

Erklärung hinzugefügt, wie von @matt wilkie gewünscht

0 Stimmen

Es amüsiert mich immer, wenn Leute sagen, dass Python die beste Sprache zum Erlernen ist, weil sie extrem gut lesbar ist. Doch je mehr "Python"-ähnlichen Code sie schreiben, desto unverständlicher ist er.

29voto

Epic Wink Punkte 641

Das Standard-Bibliotheksmodul in Python 3 ist zwar nicht dafür gedacht, aber cmd hat ein Dienstprogramm zum Drucken einer Liste von Zeichenketten in mehreren Spalten

import cmd
cli = cmd.Cmd()
cli.columnize(foolist, displaywidth=80)

Sie haben dann sogar die Möglichkeit, den Ausgabeort mit cmd.Cmd(stdout=my_stream)

2 Stimmen

Dies ist die prägnanteste und direkteste Methode für Python 3.

2 Stimmen

Funktioniert perfekt! Übergeben Sie 'shutil.get_terminal_size().columns' als 'displaywidth', um die Größe des Terminals zu verwenden

12voto

Aaron Digulla Punkte 308693

Einfach:

l = ['exiv2-devel', 'mingw-libs', 'tcltk-demos', 'fcgi', 'netcdf', 
    'pdcurses-devel',     'msvcrt', 'gdal-grass', 'iconv', 'qgis-devel', 
    'qgis1.1', 'php_mapscript']

if len(l) % 2 != 0:
    l.append(" ")

split = len(l)/2
l1 = l[0:split]
l2 = l[split:]
for key, value in zip(l1,l2):
    print '%-20s %s' % (key, value)         #python <2.6
    print "{0:<20s} {1}".format(key, value) #python 2.6+

0 Stimmen

Die nicht zur Ausgabe führt (die Daten sind in der Reihenfolge der Hauptspalten).

0 Stimmen

Ich akzeptiere dies als Antwort, weil ich es in kürzester Zeit zuverlässig hinbekommen habe - und ich kann es verstehen. Während es besser wäre, dynamische mehrspaltige Berichte zu haben, wie einige der anderen Antworten, konnte ich sie nicht dazu bringen, zuverlässig zu funktionieren (wahrscheinlich, weil ich nicht in der Lage war, der Logik in ihnen zu folgen) - manchmal werden Elemente aus der Liste fallen gelassen, wenn sie wächst/schrumpft, oder sie sind nicht mehr in Spalten angeordnet. Vielen Dank, Aaron!

12voto

ozagon Punkte 43

Inspiriert durch die Antwort von gimel, über .

import math

def list_columns(obj, cols=4, columnwise=True, gap=4):
    """
    Print the given list in evenly-spaced columns.

    Parameters
    ----------
    obj : list
        The list to be printed.
    cols : int
        The number of columns in which the list should be printed.
    columnwise : bool, default=True
        If True, the items in the list will be printed column-wise.
        If False the items in the list will be printed row-wise.
    gap : int
        The number of spaces that should separate the longest column
        item/s from the next column. This is the effective spacing
        between columns based on the maximum len() of the list items.
    """

    sobj = [str(item) for item in obj]
    if cols > len(sobj): cols = len(sobj)
    max_len = max([len(item) for item in sobj])
    if columnwise: cols = int(math.ceil(float(len(sobj)) / float(cols)))
    plist = [sobj[i: i+cols] for i in range(0, len(sobj), cols)]
    if columnwise:
        if not len(plist[-1]) == cols:
            plist[-1].extend(['']*(len(sobj) - len(plist[-1])))
        plist = zip(*plist)
    printer = '\n'.join([
        ''.join([c.ljust(max_len + gap) for c in p])
        for p in plist])
    print printer

Ergebnisse (das zweite Ergebnis entspricht Ihrer Anfrage):

>>> list_columns(foolist)
exiv2-devel       fcgi              msvcrt            qgis-devel        
mingw-libs        netcdf            gdal-grass        qgis1.1           
tcltk-demos       pdcurses-devel    iconv             php_mapscript     

>>> list_columns(foolist, cols=2)
exiv2-devel       msvcrt            
mingw-libs        gdal-grass        
tcltk-demos       iconv             
fcgi              qgis-devel        
netcdf            qgis1.1           
pdcurses-devel    php_mapscript     

>>> list_columns(foolist, columnwise=False)
exiv2-devel       mingw-libs        tcltk-demos       fcgi              
netcdf            pdcurses-devel    msvcrt            gdal-grass        
iconv             qgis-devel        qgis1.1           php_mapscript     

>>> list_columns(foolist, gap=1)
exiv2-devel    fcgi           msvcrt         qgis-devel     
mingw-libs     netcdf         gdal-grass     qgis1.1        
tcltk-demos    pdcurses-devel iconv          php_mapscript

0 Stimmen

Schlagen Sie str(c).ljust vor, denn c.ljust hat bei meinen Listenelementen nicht funktioniert. In der drittletzten Zeile, und auch len(str(item)), um die Längen in ähnlicher Weise vorzurechnen.

0 Stimmen

@ErikKruus danke, habe eine entsprechende Änderung vorgenommen. Ich erstelle jetzt eine neue Liste aus dem eingehenden obj, die in Strings konvertiert wird. Verhindert die Notwendigkeit für mehrere str() und schützt das eingehende Objekt von bearbeitet werden.

5voto

John La Rooy Punkte 278961

Die Art und Weise, wie Aaron es gemacht hat, kann mit mehr als zwei Spalten funktionieren

>>> l = ['exiv2-devel', 'mingw-libs', 'tcltk-demos', 'fcgi', 'netcdf', 
...     'pdcurses-devel',     'msvcrt', 'gdal-grass', 'iconv', 'qgis-devel', 
...     'qgis1.1', 'php_mapscript']
>>> cols = 4
>>> split=[l[i:i+len(l)/cols] for i in range(0,len(l),len(l)/cols)]
>>> for row in zip(*split):
...  print "".join(str.ljust(i,20) for i in row)
... 
exiv2-devel         fcgi                msvcrt              qgis-devel          
mingw-libs          netcdf              gdal-grass          qgis1.1             
tcltk-demos         pdcurses-devel      iconv               php_mapscript

0 Stimmen

Wenn die Länge von l nicht ein Vielfaches von cols ist, können Sie es auffüllen, indem Sie einige leere Zeichenfolgen am Ende hinzufügen

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X