How to print a list more nicely?

前端 未结 22 1276
北荒
北荒 2020-12-01 09:34

This is similar to How to print a list in Python “nicely”, but I would like to print the list even more nicely -- without the brackets and apostrophes and commas, and even b

相关标签:
22条回答
  • 2020-12-01 10:15

    this one prints list in separate columns (order is preserved)

    from itertools import zip_longest
    
    def ls(items, n_cols=2, pad=30):
        if len(items) == 0:
            return
        total = len(items)
        chunk_size = total // n_cols
        if chunk_size * n_cols < total:
            chunk_size += 1
        start = range(0, total, chunk_size)
        end = range(chunk_size, total + chunk_size, chunk_size)
        groups = (items[s:e] for s, e in zip(start, end))
        for group in zip_longest(*groups, fillvalue=''):
            template = (' ').join(['%%-%ds' % pad] * len(group))
            print(template % group)
    

    usage:

    ls([1, 2, 3, 4, 5, 6, 7], n_cols=3, pad=10)
    

    output:

    1          4          7         
    2          5                    
    3          6                    
    

    note that there may be missing columns if there is not enough number of items, because columns are filled first.

    ls([1, 2, 3, 4, 5], n_cols=4)
    

    output:

    1          3          5         
    2          4    
    
    0 讨论(0)
  • 2020-12-01 10:17
    from itertools import izip_longest, islice
    L = ['exiv2-devel', 'mingw-libs', 'tcltk-demos', 'fcgi', 'netcdf', 
        'pdcurses-devel',     'msvcrt', 'gdal-grass', 'iconv', 'qgis-devel', 
        'qgis1.1', 'php_mapscript']
    
    def columnize(sequence, columns=2):
        size, remainder = divmod(len(sequence), columns)
        if remainder: 
            size += 1
        slices = [islice(sequence, pos, pos + size) 
                  for pos in xrange(0, len(sequence), size)]
        return izip_longest(fillvalue='', *slices)
    
    for values in columnize(L):
        print ' '.join(value.ljust(20) for value in values)
    
    0 讨论(0)
  • 2020-12-01 10:19

    Inspired by gimel's answer, above.

    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
    

    Results (the second one satisfies your request):

    >>> 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 讨论(0)
  • 2020-12-01 10:19

    Here is the short and simple method:

    def printList1(list, col, STR_FMT='{}', gap=1):
        list = [STR_FMT.format(x).lstrip() for x in list]
        FMT2 = '%%%ds%%s' % (max(len(x) for x in list)+gap)
        print(''.join([FMT2 % (v, "" if (i+1) % col else "\n") for i, v in enumerate(list)]))
    

    Then here is the better method which can turn off the constant width across the entire list instead optimizing it across the columns, restrict the number of columns to fit the max characters per line or find the optimal number of columns to fit the max characters per line, then force left or right justify, and can still can take the optional format string, and gap width between each column.

    def printList2(list, col=None, gap=2, uniform=True, ljust=True, STR_FMT="{}", MAX_CHARS=120, end='\n'):
       list = [STR_FMT.format(x).strip() for x in list]
       Lmax, valid, valid_prev, cp, c = [MAX_CHARS+1], None, None, 1, max(col,1) if col else 1
       LoL_prev, Lmax_prev = [], []
    
       while True:
           LoL = [list[i::c] for i in range(c)]
           Lmax = [max(len(x)+gap for x in L) for L in LoL]    # Find max width of each column with gap width
           if uniform:                                         # Set each max column width to max across entire set.
               Lmax = [max(Lmax) for m in Lmax]
    
           valid_prev, valid = valid, sum(Lmax) <= MAX_CHARS
    
           if (col and (valid or (c == 1))) or not MAX_CHARS:  # If column and valid strlen or MAX_CHARS is empty
               break
           elif valid_prev and not valid_prev == valid:        # If valid_prev exist
               c = cp if valid_prev and not valid else c
               LoL, Lmax = (LoL_prev, Lmax_prev) if valid_prev else (LoL, Lmax)
               break
    
           LoL_prev, Lmax_prev = LoL, Lmax
           cp, c = c, (c + (+1 if valid else -1))
      
       ljust = '-' if ljust else ''
       FMT = ["%%%s%ds%s" % (ljust, max(Lmax) if uniform else m, end if i+1 == c else '') for i, m in enumerate(Lmax)]
       outStr = ''.join([''.join([f % v for v, f in zip(L, FMT)]) for L in zip(*LoL)])
       remStr = ''.join([f % v for v, f in zip(list[c * (len(list) // c):], FMT)])
       print(outStr+(remStr+end if remStr else remStr), end='')
    

    Testing w/ outputs:

    >>> foolist = ['exiv2-devel', 'mingw-libs', 'tcltk-demos', 'fcgi', 'netcdf',
                 'pdcurses-devel', 'msvcrt', 'gdal-grass', 'iconv', 'qgis-devel', 
                 'qgis1.1', 'php_mapscript']
    >>> printList2(foolist)
    exiv2-devel     mingw-libs      tcltk-demos     fcgi            netcdf          pdcurses-devel  msvcrt          
    gdal-grass      iconv           qgis-devel      qgis1.1         php_mapscript   
    
    >>> printList2(foolist, MAX_CHARS=48, uniform=False, gap=3)
    exiv2-devel   mingw-libs   tcltk-demos      
    fcgi          netcdf       pdcurses-devel   
    msvcrt        gdal-grass   iconv            
    qgis-devel    qgis1.1      php_mapscript    
    
    >>> printList2(foolist, col=2, MAX_CHARS=48, uniform=False, gap=3)
    exiv2-devel   mingw-libs       
    tcltk-demos   fcgi             
    netcdf        pdcurses-devel   
    msvcrt        gdal-grass       
    iconv         qgis-devel       
    qgis1.1       php_mapscript    
    
    >>> printList2(foolist, col=2, MAX_CHARS=48, uniform=False, ljust=False, gap=2)
      exiv2-devel      mingw-libs
      tcltk-demos            fcgi
           netcdf  pdcurses-devel
           msvcrt      gdal-grass
            iconv      qgis-devel
          qgis1.1   php_mapscript
    
    >>> printList2(foolist, col=10, MAX_CHARS=48, uniform=True, ljust=False, gap=2)
         exiv2-devel      mingw-libs     tcltk-demos
                fcgi          netcdf  pdcurses-devel
              msvcrt      gdal-grass           iconv
          qgis-devel         qgis1.1   php_mapscript
    
    >>> from math import pi
    >>> FloatList = [pi**(i+1) for i in range(32)]
    >>> printList2(FloatList, STR_FMT="{:.5g},", col=7, ljust=False)
          3.1416,      9.8696,      31.006,      97.409,      306.02,      961.39,      3020.3,
          9488.5,       29809,       93648,   2.942e+05,  9.2427e+05,  2.9037e+06,  9.1222e+06,
      2.8658e+07,  9.0032e+07,  2.8284e+08,  8.8858e+08,  2.7916e+09,    8.77e+09,  2.7552e+10,
      8.6556e+10,  2.7192e+11,  8.5427e+11,  2.6838e+12,  8.4313e+12,  2.6488e+13,  8.3214e+13,
      2.6142e+14,  8.2129e+14,  2.5802e+15,  8.1058e+15,
    
    0 讨论(0)
提交回复
热议问题