Как распечатать список более красиво? - PullRequest
16 голосов
/ 06 октября 2009

Это похоже на Как напечатать список в Python «красиво» , но я бы хотел напечатать список еще лучше - без скобок и апострофов и запятых, а еще лучше в столбцах .

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

evenNicerPrint(foolist)

Желаемый результат:

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

спасибо!

Ответы [ 18 ]

0 голосов
/ 04 марта 2019

Мне нужно было настроить каждый из столбцов. Я реализовал этот код

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

Пример:

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)

Выход:

blablablablablablabla   exiv2-devel      fafafafafafa    fcgi        
gdal-grass              iconv            mingw-libs      msvcrt      
netcdf                  pdcurses-devel   php_mapscript   qgis-devel  
qgis1.1                 tcltk-demos   
0 голосов
/ 11 февраля 2019

В качестве расширения @Aman ниже приведена функция, которая берет список строк и выводит их в столбцах в зависимости от размера терминала.

import os
def column_display(input_list):
    '''
    Used to create a structured column display based on the users terminal size

    input_list : A list of string items which is desired to be displayed
    '''
    rows, columns = os.popen('stty size', 'r').read().split()
    terminal_space_eighth = int(columns)/8
    terminal_space_seventh = int(columns)/7
    terminal_space_sixth = int(columns)/6
    terminal_space_fifth = int(columns)/5
    terminal_space_quarter = int(columns)/4
    terminal_space_third = int(columns)/3
    terminal_space_half = int(columns)/2
    longest_string = max(input_list, key=len)
    longest_length = len(longest_string) + 1
    list_size = len(input_list)

    if longest_length > terminal_space_half:
         for string in input_list:
             print(string)
    elif terminal_space_eighth >= longest_length and list_size >= 8:
         for a,b,c,d,e,f,g,h in zip(input_list[::8],input_list[1::8],input_list[2::8], input_list[3::8], input_list[4::8], input_list[5::8], input_list[6::8], input_list[7::8]):
             column_space = '{:<%s}{:<%s}{:<%s}{:<%s}{:<%s}{:<%s}{:<%s}{:<}' % (longest_length, longest_length, longest_length, longest_length, longest_length, longest_length, longest_length )
             output = column_space.format(a,b,c,d,e,f,g,h)
             print(output)
    elif terminal_space_seventh >= longest_length and list_size >= 7:
        for a,b,c,d,e,f,g in zip(input_list[::7],input_list[1::7],input_list[2::7], input_list[3::7], input_list[4::7], input_list[5::7], input_list[6::7]):
             column_space = '{:<%s}{:<%s}{:<%s}{:<%s}{:<%s}{:<%s}{:<}' % (longest_length, longest_length, longest_length, longest_length, longest_length, longest_length)
             output = column_space.format(a,b,c,d,e,f,g)
             print(output)
    elif terminal_space_sixth >= longest_length and list_size >= 6:
         for a,b,c,d,e,f in zip(input_list[::6],input_list[1::6],input_list[2::6], input_list[3::6], input_list[4::6], input_list[5::6]):
             column_space = '{:<%s}{:<%s}{:<%s}{:<%s}{:<%s}{:<}' % (longest_length, longest_length, longest_length, longest_length, longest_length)
             output = column_space.format(a,b,c,d,e,f)
             print(output)
    elif terminal_space_fifth >= longest_length and list_size >= 5:
        for a,b,c,d,e in zip(input_list[::5],input_list[1::5],input_list[2::5], input_list[3::5], input_list[4::5]):
            column_space = '{:<%s}{:<%s}{:<%s}{:<%s}{:<}' % (longest_length, longest_length, longest_length, longest_length)
            output = column_space.format(a,b,c,d,e)
            print(output)
    elif terminal_space_quarter >= longest_length and list_size >= 4:
        for a,b,c,d in zip(input_list[::4],input_list[1::4],input_list[2::4], input_list[3::4]):
            column_space = '{:<%s}{:<%s}{:<%s}{:<}' % (longest_length, longest_length, longest_length)
            output = column_space.format(a,b,c,d)
            print(output)
    elif terminal_space_third >= longest_length and list_size >= 3:
        for a,b,c in zip(input_list[::3],input_list[1::3],input_list[2::3]):
            column_space = '{:<%s}{:<%s}{:<}' % (longest_length, longest_length)
            output = column_space.format(a,b,c)
            print(output)
    elif terminal_space_half >= longest_length and list_size >= 2:
        for a,b in zip(input_list[::2],input_list[1::2]):
            column_space = '{:<%s}{:<}' % longest_length
            output = column_space.format(a,b)
            print(output)

В качестве объяснения это делает несколько разных вещей.

Сначала получает число столбцов для терминала текущего пользователя, используя os.popen.

Второй он принимает количество столбцов и делит пополам, увеличивая до восьмого. Это будет использоваться для сравнения самой длинной строки в списке, чтобы определить количество столбцов, наиболее подходящих для этого.

Третий - самая длинная строка списка, извлекаемая с помощью функции max (), встроенной в python.

Forth длина самой длинной строки берется и затем добавляется к ней для заполнения. Длина списка также принимается за то, чтобы, если список меньше 8 элементов, в нем было указано только количество элементов, которые существуют.

Пятая самая длинная длина строки сравнивается с каждым из оконечных пространств от одного столбца до восьми. Если столбец больше или равен длине, его можно использовать. Например, самая длинная строка равна 10, а столбцы, разделенные на восемь (Terminal_space_eighth), равны 8, а столбцы, разделенные на семь (Terminal_space_seventh), равны 12, будет семь столбцов. Их будет семь, потому что самая длинная строка может уместиться в 12 символов, но не в 8 символов.

Стоит также отметить, что длина списка учитывается, чтобы предотвратить создание большего количества столбцов, чем элементов списка.

Шестое - это расширение объяснения @Aman: https://stackoverflow.com/a/1524132/11002603

Индексация Позвольте мне представить число, определенное размером терминала для примера. input_list[::i] Это выбирает элемент в i. Добавление числа в начале, такого как input_list[1::i], смещает начальную точку (помните, что python считает 0 действительным числом, поэтому изначально оно не используется.)

Архивирование

Zip используется для создания кортежа с элементами списка. Например, список вывода будет выглядеть примерно так:

zip([string1,string2,string3], [string4,string5, string6], [string7,string8,string9])
output : [(string1,string4,string7), (string2,string5, string8), (string3,string6,string9)]

Использование вместе В зависимости от количества столбцов буквы просто используются для представления разбиения. Так, например, если в терминале помещается только 5 столбцов, будет использовано следующее

for a,b,c,d,e in zip(input_list[::5],input_list[1::5],input_list[2::5], input_list[3::5], input_list[4::5]):

Это будет принимать кортежи, созданные из архива, и сохранять их как переменные a, b, c, d и e, чтобы мы могли вызывать их в цикле.

Пространство столбца затем используется для форматирования каждого из a, b, c, d и e в соответствующие столбцы, и здесь определяется длина каждого столбца. Длина основана на длине строки, определенной выше.

0 голосов
/ 20 сентября 2018

Уже существует множество ответов, но я поделюсь своим решением, которое помимо печати списка в несколько столбцов, оно также динамически выбирает количество столбцов, исходя из ширины терминала и самой длинной строки в списке.

import os
cols = os.popen('stty size', 'r').read().split()[1]

def print_multicol(my_list):
    max_len = len(max(my_list,key=len)) + 2
    ncols = (int(cols) -4 ) / max_len
    while my_list:
        n = 0
        while n < ncols:
            if len(my_list) > 0 :
                fstring = "{:<"+str(max_len)+"}"
                print fstring.format(my_list.pop(0)),
            n += 1
        print

a_list = "a ab abc abcd abcde b bc bcde bcdef c cde cdef cdfg d de defg"
a_list += "defgh e ef efg efghi efghij f fg fgh fghij fghijk"

print_multicol(a_list.split())
0 голосов
/ 19 сентября 2017
[print('{:20}'.format(key), end='\t') if (idx + 1) % 5 else print(key, end='\n') for idx, key in enumerate(list_variable)]

или

for idx, key in enumerate(list_variable):
    if (idx + 1) % 5:
        print('{:20}'.format(key), end='\t')
    else:
        print(key, end='\n')
0 голосов
/ 05 марта 2017

Полезно учитывать неровные столбцы, не зная заранее, сколько столбцов вы можете разместить:

>>> 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

Для вашего примера:

>>> 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

Вот код. Обратите внимание, что он также обрабатывает слова с цветовыми кодами ANSI (например, из пакета colorama) - они не будут портить ширину столбцов.

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 голосов
/ 31 декабря 2015

Вот решение в python 3.4, которое автоматически определяет ширину терминала и учитывает ее. Протестировано на Linux и Mac.

def column_print(list_to_print, column_width=40):
    import os
    term_height, term_width = os.popen('stty size', 'r').read().split()
    total_columns = int(term_width) // column_width
    total_rows = len(list_to_print) // total_columns
    # ceil
    total_rows = total_rows + 1 if len(list_to_print) % total_columns != 0 else total_rows

    format_string = "".join(["{%d:<%ds}" % (c, column_width) \
            for c in range(total_columns)])
    for row in range(total_rows):
        column_items = []
        for column in range(total_columns):
            # top-down order
            list_index = row + column*total_rows
            # left-right order
            #list_index = row*total_columns + column
            if list_index < len(list_to_print):
                column_items.append(list_to_print[list_index])
            else:
                column_items.append("")
        print(format_string.format(*column_items))
0 голосов
/ 04 декабря 2014

Нашел этот вопрос как выполненное практически одно и то же задание. И я создал функцию для печати списка в несколько столбцов с количеством столбцов в качестве параметра. Может быть, не так элегантно, как однострочные решения, но это может быть полезно для кого-то.

Однако он обрабатывает неполные списки, например: может печатать список из 11 в 3 ряда.

Функция разделена для лучшей читаемости:

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))

и часть вызова:

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 голосов
/ 06 октября 2009
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)
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...