与this相同的问题,但对于python。如果我有一个清单
['a','b','cdefg','jk','lmnopqr','st','uv','wxyz',1,2,3,4]
我想在bash中打印类似于ls命令的默认输出,类似于
[ 'a', 'b', 'cdefg',
'jk', 'st', 'lm',
'no', 'pqrstuv', 'wxyz',
1, 2, 3,
4, ]
目标是一次在屏幕上最大化可视分析数据。我只能找到pprint库,对于简单列表,它可以打印为默认值,也可以打印每行一个。这样的事情是否存在?
答案 0 :(得分:3)
感谢大家的想法,并澄清确实没有现成的解决方案。我编码了我想要的,代码如下。在宽度为80个字符的终端
pprint_list( [ string.lowercase[i % 26]*random.randint(1,20) for i in range(8) ] )
打印为
[ 'aaaa', 'bbbbbbbbbbbbbbb', 'ccccccccccccccccccc', 'd',
'eeeeeeeeeee', 'ffffffffffffffff', 'gggggggggggggggg', 'h' ]
查看代码显示,显然有一些开销计算如何调整列的大小,更多的条目和更宽的终端需要更多的计算,但将条目数从8移到50000并没有多少滞后时间,所以我觉得我很满意。
此代码依赖于get_terminal_size函数here。
#!/usr/bin/env python
def pprint_list(input_list):
(term_width, term_height) = get_terminal_size()
if len( str(input_list) ) <= term_width:
print input_list
return
repr_list = [repr(x) for x in input_list]
min_chars_between = 3 # a comma and two spaces
usable_term_width = term_width - 3 # For '[ ' and ']' at beginning and end
min_element_width = min( len(x) for x in repr_list ) + min_chars_between
max_element_width = max( len(x) for x in repr_list ) + min_chars_between
if max_element_width >= usable_term_width:
ncol = 1
col_widths = [1]
else:
# Start with max possible number of columns and reduce until it fits
ncol = min( len(repr_list), usable_term_width / min_element_width )
while True:
col_widths = [ max( len(x) + min_chars_between \
for j, x in enumerate( repr_list ) if j % ncol == i ) \
for i in range(ncol) ]
if sum( col_widths ) <= usable_term_width: break
else: ncol -= 1
sys.stdout.write('[ ')
for i, x in enumerate(repr_list):
if i != len(repr_list)-1: x += ','
sys.stdout.write( x.ljust( col_widths[ i % ncol ] ) )
if i == len(repr_list) - 1:
sys.stdout.write(']\n')
elif (i+1) % ncol == 0:
sys.stdout.write('\n ')
答案 1 :(得分:2)
def columnify(iterable):
# First convert everything to its repr
strings = [repr(x) for x in iterable]
# Now pad all the strings to match the widest
widest = max(len(x) for x in strings)
padded = [x.ljust(widest) for x in strings]
return padded
现在,您应该可以使用pprint.pprint(compact=True)
或textwrap
或其他工具来获取所需的格式。
但是如果你想手动完成,那么做任何你想做的事情并不难。例如:
def colprint(iterable, width=72):
columns = columnify(iterable)
colwidth = len(columns[0])+2
perline = (width-4) // colwidth
print('[ ', end='')
for i, column in enumerate(columns):
print(column, end=', ')
if i % perline == perline-1:
print('\n ', end='')
print(' ]')
所以:
>>> arr = ['a', 'b', 'cdefg', 'jk', 'lmnopqr', 'st', 'uv', 'wxyz', 1, 2, 3, 4]
>>> colprint(arr, 60)
[ 'a' , 'b' , 'cdefg' , 'jk' , 'lmnopqr',
'st' , 'uv' , 'wxyz' , 1 , 2 ,
3 , 4 , ]
这仍然不能准确地告诉你ls
的作用;例如,ls
有一些启发式方法可以确保文件名太长&#34;不要计入最大宽度,而是跨越多列。如果你真的想要完成与ls
相同的所有 ,你可能需要查看源代码并从C转换为Python ......
另外,请查看pprint
。每当模块的文档以源代码的链接开始时,这意味着该模块可以作为有用的示例代码,并且可以自己使用。因此,如果您想查看它用于确定何时分割线的规则(基于compact
标志以及宽度),您应该能够从中找出它。