How to print a list more nicely?

前端 未结 22 1278
北荒
北荒 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:03

    Found this question as a met almost the same task. And I've created function to print list in multi columns with the number of columns as parameter. Maybe not so elegant as one-liner solutions, but it could be useful for someone.

    However, it handles incomplete lists, ex.: it can print list of 11 in 3 rows.

    Function splitted for better readability:

    def is_printable(my_list):
        return len(my_list) > 0
    
    def create_empty_list(columns):
        result = []
        for num in range(0, columns):
            result.append([])
        return result
    
    def fill_empty_list(empty_list, my_list, columns):
        column_depth = len(my_list) / columns if len(my_list) % columns == 0 else len(my_list) / columns + 1
        item_index = 0
        for column in range(0, columns):
            while len(empty_list[column]) < column_depth:
                if item_index < len(my_list):
                    empty_list[column].append(my_list[item_index])
                else:
                    empty_list[column].append(" ")  # last column could be incomplete, fill it with space
                item_index += 1
    
    def print_list_in_columns(my_list, columns=1):
        if not is_printable(my_list):
            print 'Nothing to print, sorry...'
            return
        column_width = 25  #(in symbols) Also can be calculated automatically  
        list_to_print = create_empty_list(columns)
        fill_empty_list(list_to_print, my_list, columns)
        iterators = ["it" + str(i) for i in range(0, columns)]
        for iterators in zip(*list_to_print):
            print ("".join(str.ljust(i, column_width) for i in iterators))
    

    and the call part:

    foolist = ['exiv2-devel', 'mingw-libs', 'tcltk-demos', 'fcgi', 'netcdf', 
        'pdcurses-devel',     'msvcrt', 'gdal-grass', 'iconv', 'qgis-devel', 
        'qgis1.1', 'php_mapscript']
    
    print_list_in_columns(foolist, 2)
    
    0 讨论(0)
  • 2020-12-01 10:04

    Although not designed for it, the standard-library module cmd has a utility for printing a list of strings in multiple columns

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

    You even then have the option of specifying the output location, with cmd.Cmd(stdout=my_stream)

    0 讨论(0)
  • 2020-12-01 10:05

    See formatting-a-list-of-text-into-columns,

    A general solution, handles any number of columns and odd lists. Tab characters separate columns, using generator expressions to save space.

    def fmtcols(mylist, cols):
        lines = ("\t".join(mylist[i:i+cols]) for i in xrange(0,len(mylist),cols))
        return '\n'.join(lines)
    
    0 讨论(0)
  • 2020-12-01 10:05

    It's useful to allow for uneven columns, without having to know in advance how many columns you can fit:

    >>> words = [string.ascii_lowercase] + list(string.ascii_lowercase)
    >>> print format_list(words)
    abcdefghijklmnopqrstuvwxyz  b  d  f  h  j  l  n  p  r  t  v  x  z
    a                           c  e  g  i  k  m  o  q  s  u  w  y
    

    For your example:

    >>> foolist = ['exiv2-devel', 'mingw-libs', 'tcltk-demos', 'fcgi',
    ... 'netcdf', 'pdcurses-devel', 'msvcrt', 'gdal-grass', 'iconv',
    ... 'qgis-devel', 'qgis1.1', 'php_mapscript']
    >>> print format_list(foolist, spacing=4, width=31)
    exiv2-devel       msvcrt
    mingw-libs        gdal-grass
    tcltk-demos       iconv
    fcgi              qgis-devel
    netcdf            qgis1.1
    pdcurses-devel    php_mapscript
    

    Here is the code. Note that it also handles words with ANSI color codes (such as from the colorama package) - they won't mess up the column widths.

    ansi_pattern = re.compile(r'\x1b\[\d{1,2}m')
    
    
    def get_nchars(string):
        """Return number of characters, omitting ANSI codes."""
        return len(ansi_pattern.sub('', string))
    
    
    def format_list(items, indent=0, spacing=2, width=79):
        """Return string listing items along columns.
    
        items : sequence
            List of items to display that must be directly convertible into
            unicode strings. ANSI color codes may be present, and are taken
            into account in determining column widths
        indent : int
            Number of spaces in left margin.
        spacing : int
            Number of spaces between columns.
        width : int
            Maximum number of characters per line, including indentation.
        """
        if not items:
            return u''
        # Ensure all items are strings
        items = [unicode(item) for item in items]
        # Estimate number of columns based on shortest and longest items
        minlen = min(get_nchars(item) for item in items)
        maxlen = max(get_nchars(item) for item in items)
        # Assume one column with longest width, remaining with shortest.
        # Use negative numbers for ceiling division.
        ncols = 1 - (-(width - indent - maxlen) // (spacing + min(1, minlen)))
        ncols = max(1, min(len(items), ncols))
    
        # Reduce number of columns until items fit (or only one column)
        while ncols >= 1:
            # Determine number of rows by ceiling division
            nrows = -(-len(items) // ncols)
            # Readjust to avoid empty last column
            ncols = -(-len(items) // nrows)
            # Split items into columns, and test width
            columns = [items[i*nrows:(i+1)*nrows] for i in range(ncols)]
            totalwidth = indent - spacing + sum(
                spacing + max(get_nchars(item) for item in column)
                for column in columns
                )
            # Stop if columns fit. Otherwise, reduce number of columns and
            # try again.
            if totalwidth <= width:
                break
            else:
                ncols -= 1
    
        # Pad all items to column width
        for i, column in enumerate(columns):
            colwidth = max(get_nchars(item) for item in column)
            columns[i] = [
                item + ' ' * (colwidth - get_nchars(item))
                for item in column
                ]
    
        # Transpose into rows, and return joined rows
        rows = list(itertools.izip_longest(*columns, fillvalue=''))
        return '\n'.join(
            ' ' * indent + (u' ' * spacing).join(row).rstrip()
            for row in rows
            )
    
    0 讨论(0)
  • 2020-12-01 10:05

    I needed to adjust each of the columns. I have implemented this code

    def print_sorted_list(data, columns):
        if data:
            gap = 2
            ljusts = {}
            for count, item in enumerate(sorted(data), 1):
                column = count % columns
                ljusts[column] = len(item) if (column not in ljusts) else max(ljusts[column], len(item))
    
            for count, item in enumerate(sorted(data), 1):
                print item.ljust(ljusts[count % columns] + gap),
                if (count % columns == 0) or (count == len(data)):
                    print
    

    Example:

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

    Output:

    blablablablablablabla   exiv2-devel      fafafafafafa    fcgi        
    gdal-grass              iconv            mingw-libs      msvcrt      
    netcdf                  pdcurses-devel   php_mapscript   qgis-devel  
    qgis1.1                 tcltk-demos   
    
    0 讨论(0)
  • 2020-12-01 10:07

    For Python >=3.6, slight update to @JoshuaZastrow's answer using f-strings and adding clear method to adjust columns

    cols = 5
    [print(f'{key:20}', end='\t') if (idx + 1) % cols else print(f'{key}') for idx, key in enumerate(list_variable)]
    

    or

    cols = 5
    for idx, key in enumerate(list_variable):
        if (idx + 1) % cols:
            print(f'{key:20}', end='\t')
        else:
            print(f'{key}')
    
    0 讨论(0)
提交回复
热议问题