web-dev-qa-db-ja.com

リストをよりきれいに印刷するにはどうすればよいですか?

これは リストをPython“ nicely” で印刷する方法)に似ていますが、リストをさらにうまく印刷したいのですが、角かっことアポストロフィを付けずにカンマ、および列でさらに優れています。

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 

ありがとう!

17
matt wilkie

シンプル:

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+
11
Aaron Digulla

この回答は、@ Aaron Digullaによる回答と同じ方法を使用していますが、Pythonの構文が少し多くなっています。上記の回答のいくつかが理解しやすくなる可能性があります。

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

これは、任意の数の列または可変列に簡単に適応でき、@ gnibblerによる回答のようなものになります。画面幅に合わせて間隔を調整できます。


更新:要求に応じた説明。

インデックス作成

foolist[::3]foolistの3つおきの要素を選択します。 foolist[1::3]は、2番目の要素から始まる3つおきの要素を選択します(pythonはゼロインデックスを使用するため、「1」)。

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

Zip

リスト(または他の反復可能オブジェクト)を圧縮すると、リストの要素のタプルが生成されます。例えば:

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

一緒に

これらのアイデアをまとめると、次のような解決策が得られます。

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

ここでは、最初にfoolistの3つの「スライス」を生成します。各スライスは、3分の1の要素ごとにインデックスが付けられ、1つオフセットされています。個別に、それらはそれぞれリストの3分の1しか含まれていません。これらのスライスを圧縮して反復すると、各反復でfoolistの3つの要素が得られます。

それが私たちが望んでいたことです:

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]

の代わりに:

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

ギメルの答えに触発されて、 上記

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

結果(2番目のものはあなたの要求を満たします):

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

formatting-a-list-of-text-into-columns 、を参照してください。

一般的な解決策は、任意の数の列と奇数リストを処理します。タブ文字は列を区切り、ジェネレータ式を使用してスペースを節約します。

def fmtcols(mylist, cols):
    lines = ("\t".join(mylist[i:i+cols]) for i in xrange(0,len(mylist),cols))
    return '\n'.join(lines)
5
gimel

アーロンが行った方法は、3つ以上の列で機能します


>>> 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       
5
John La Rooy

データが指定した形式の場合は、もう少し手間がかかります


>>> d = ['exiv2-devel', 'mingw-libs', 'tcltk-demos', 'fcgi', 'netcdf', 
...     'pdcurses-devel',     'msvcrt', 'gdal-grass', 'iconv', 'qgis-devel', 
...     'qgis1.1', 'php_mapscript']
>>> print "\n".join("%-20s %s"%(d[i],d[i+len(d)/2]) for i in range(len(d)/2))
exiv2-devel          msvcrt
mingw-libs           gdal-grass
tcltk-demos          iconv
fcgi                 qgis-devel
netcdf               qgis1.1
pdcurses-devel       php_mapscript
3
John La Rooy

このようなものはどうですか?

def strlistToColumns( strl, maxWidth, spacing=4 ):

longest = max([len(s) for s in strl])
width = longest+spacing

# compute numCols s.t. (numCols-1)*(longest+spacing)+longest < maxWidth
numCols = 1 + (maxWidth-longest)//width
C = range(numCols)

# If len(strl) does not have a multiple of numCols, pad it with empty strings
strl += [""]*(len(strl) % numCols)
numRows = len(strl)/numCols
colString = ''

for r in range(numRows):
    colString += "".join(["{"+str(c)+":"+str(width)+"}" \
        for c in C]+["\n"]).format(*(strl[numCols*r+c] \
        for c in C))

return colString 


if __name__ == '__main__':

fruits = ['Apple', 'banana', 'cantaloupe', 'durian', 'elderberry',         \
          'fig', 'grapefruit', 'honeydew', 'indonesian Lime', 'jackfruit', \
          'kiwi', 'lychee', 'mango', 'orange', 'pomegranate', 'quince',    \
          'raspberry', 'tangerine', 'ugli fruit', 'watermelon', 'xigua',
          'yangmei', 'zinfandel grape']

cols = strlistToColumns( fruits, 80 )

print(cols)

出力

Apple              banana             cantaloupe         durian
elderberry         fig                grapefruit         honeydew
indonesian Lime    jackfruit          kiwi               lychee
mango              orange             pomegranate        quince
raspberry          tangerine          ugli fruit         watermelon
xigua              yangmei            zinfandel grape
1

これが私の解決策です。 ( GitHub Gistにコピー

入力として端子幅を取り、それに収まる数の列のみを表示します。

def col_print(lines, term_width=80, indent=0, pad=2):
  n_lines = len(lines)
  if n_lines == 0:
    return

  col_width = max(len(line) for line in lines)
  n_cols = int((term_width + pad - indent)/(col_width + pad))
  n_cols = min(n_lines, max(1, n_cols))

  col_len = int(n_lines/n_cols) + (0 if n_lines % n_cols == 0 else 1)
  if (n_cols - 1) * col_len >= n_lines:
    n_cols -= 1

  cols = [lines[i*col_len : i*col_len + col_len] for i in range(n_cols)]

  rows = list(Zip(*cols))
  rows_missed = Zip(*[col[len(rows):] for col in cols[:-1]])
  rows.extend(rows_missed)

  for row in rows:
    print(" "*indent + (" "*pad).join(line.ljust(col_width) for line in row))
1
John

n列の解を @ Aman の答えに拡張します

def printMultiCol(l, n_cols, buffer_len=5):
    """formats a list of strings, l, into n_cols with a separation of buffer_len"""
    if not l: return [] # return if not iterable!
    max_l = max(map(len, l))
    formatter = '{{:<{max_l}}}'.format(max_l=max_l+buffer_len)*n_cols
    Zip_me_up = [l[i::n_cols] for i in xrange(n_cols)]
    max_Zip_l = max(map(len, Zip_me_up))
    Zip_me_up = map(lambda x: x + ['']*(max_Zip_l-len(x)), Zip_me_up)
    return [formatter.format(*undress_me) for undress_me in Zip(*Zip_me_up)]

テスト

ランダムな文字列の長さでテストを設定します

import random
list_length = 16
random_strings = [
    ''.join(random.choice('spameggsbaconbeanssausage') 
    for x in range(random.randint(1,10)))
    for i in xrange(list_length)
]

print 'for 4 columns (equal length cols) ...\n{}'.format(
    '\n'.join(printMultiCol(random_strings, 4))
)
print 'for 7 columns (odd length cols) ...\n{}'.format(
    '\n'.join(printMultiCol(random_strings, 5))
)

戻る

## -- End pasted text --
for 4 columns (equal length cols) ...
sgsebpasgm     assgaesse      ossmeagan      ebesnagec
mees           eeges          m              gcb
sm             pbe            bbgaa          ganopabnn
bmou           asbegu         a              psoge


for 7 columns (odd length cols) ...
sgsebpasgm     assgaesse      ossmeagan      ebesnagec      mees
eeges          m              gcb            sm             pbe
bbgaa          ganopabnn      bmou           asbegu         a
psoge
1
[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')
1
Joshua Zastrow

各列を調整する必要がありました。私はこのコードを実装しました

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
David Miró

以下の@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)

説明として、これはいくつかの異なることを行います。

Firstos.popenを使用して、現在のユーザーの端末の列数を取得します。

Second列の数を取り、半分に分割して8番目に増やします。これは、リスト内の最長の文字列を比較して、これに最適な列の数を決定するために使用されます。

Thirdは、ビルドインpython function max()を使用してプルされたリストの最長の文字列です。

Forth最長の文字列の長さが取得され、パディングのために1つ追加されます。リストの長さも考慮されるため、リストが8アイテム未満の場合は、存在するアイテムの数のみがリストされます。

5番目の最長の文字列長は、1列から8列までの各終端スペースと比較されます。列が長さ以上の場合は、それを使用できます。たとえば、最長の文字列は10で、列を8で割った値(terminal_space_eighth)は8ですが、列を7で割った値(terminal_space_seventh)は12で、7つの列があります。最長の文字列は12文字に収まるが、8文字には収まらないため、7文字になります。

リストアイテムよりも多くの列が作成されないように、リストの長さが考慮されていることにも注意してください。

6番目は@Amanによる説明の拡張です:https://stackoverflow.com/ a/1524132/110026

Indexingこの例のために、端末サイズによって決定される数をiで表します。 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]):

これにより、zipから作成されたタプルが取得され、a、b、c、d、およびe変数として格納されるため、ループ内でそれらを呼び出すことができます。

次に、列スペースは、a、b、c、d、およびeのそれぞれをそれぞれの列にフォーマットするために使用され、各列の長さが決定されます。長さは、上記で決定された文字列の長さに基づいています。

0
lunnydan

これが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
Bryant Kou

この質問は、ほぼ同じタスクを満たしていることがわかりました。そして、列数をパラメータとしてリストを複数列に出力する関数を作成しました。ワンライナーソリューションほどエレガントではないかもしれませんが、誰かにとっては役立つかもしれません。

ただし、不完全なリストは処理します。例: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
Dragon Margarin

これが簡単な方法です。説明については、インラインコメントを参照してください。

import shutil
import itertools
from functools import reduce


def split_list(lst, ncols):
    """Split list into rows"""
    return itertools.Zip_longest(
        *[lst[i::ncols] for i in range(ncols)], fillvalue=""
    )
    # -- Alternatively --
    # import numpy as np
    # array = np.array(lst)
    # nrows = array.size / ncols + 1
    # return np.array_split(array, int(nrows))


def print_in_columns(lst):
    """Print a list in columns."""
    # Find maximum length of a string in colors_list
    colsize = reduce(lambda x, y: max(x, len(y)), lst, 0)
    # Terminal width
    maxcols = shutil.get_terminal_size()[0]
    ncols = maxcols / (colsize + 1)
    rows = split_list(lst, int(ncols))

    print(
        # Join rows
        "\n".join(
            (
                # Fill items left justified
                " ".join(item.ljust(colsize) for item in row)
                for row in rows
            )
        )
    )
0
jadelord

何列に収まるかを事前に知らなくても、不均一な列を許可すると便利です。

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

すでにたくさんの答えがありますが、リストを複数の列に出力するだけでなく、端末の幅とリストの最長の文字列から列の数を動的に選択するソリューションを共有します。

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