I've got a 2D list in Python like this:
[['Something', 'Someth开发者_如何学编程ing else', 'Another thing'],
['Other things', 'More data', 'Element'],
['Stuff', 'data', 'etc']]
I want it to be printed out like this:
Something Something else Another thing Other things More data Element Stuff data etc
l = [['Something', 'Something else', 'Another thing'],
['Other things', 'More data', 'Element'],
['Stuff', 'data', 'etc']]
sub1 = [
[s.ljust(max(len(i) for i in column)) for s in column]
for column in zip(*l)]
for p in [" ".join(row) for row in zip(*sub1)]: print p
Here, first the list gets transformed with zip(*l)
: each of the sub lists gets passed as an own argument to zip()
. The result is a list which combines the n-th entries of each old list, so you get [['Something', 'Other things', 'Stuff'], ['Something else', 'More data', 'data'], ...]
.
Then the entries whose lengths are to be matched are in the same column
. In each of these column
s the strings are ljust()
ed to the greatest length in the group.
After that, the new list with the adjusted lengths is transformed again - in the same way as above - and the components joined with a " "
in-between.
The resulting 1D list is then printed entry by entry.
You can use the string format
method, or even the older string interpolation operator, to place strings into padded, fixed length fields. See format strings documentation.
A loop using this need not be ugly.
from itertools import chain
ll = [['Something', 'Something else', 'Another thing'],
['Other things', 'More data', 'Element'],
['Stuff', 'data', 'etc']]
# get the length of the longest item.
# For simplicity, I use the same width for all columns
a = max(len(s) for s in chain.from_iterable(ll)) + 1
# make a format string with the max
f = ('{:<' + str(a) + '}').format
# print the list
print '\n'.join(''.join(f(s) for s in sl) for sl in ll)
I do not know if such a function exists in the python library (and I doubt you would find one), but a doubly nested loop seems to be the easiest solution. Simply concatenate the strings at the end of the inner loop with an empty space (but I guess from the way you asked the question, you want them aligned, so use the tab escape character "\t"). Print them after you exit the inner loop, and that should do it.
EDIT: I see I was right about the tab spacing ... the tab escape character is equivalent to pressing the tab key, if you need more space, use multiple ones in a row "\t\t".
li = [['Something', 'Something else', 'Another thing'],
['Other things', 'More data', 'Element'],
['Stuff', 'data', 'etc']]
print li,'\n'
print "tuple( max(map(len,x)) for x in zip(*li)) == ",\
tuple( max(map(len,x)) for x in zip(*li))
print
patform = '%%-%ss %%-%ss %%-%ss' % tuple( max(map(len,x)) for x in zip(*li))
print '\n'.join(patform % tuple(x) for x in li)
# OR
print
patform = '{:<%s} {:<%s} {:<%s}' % tuple( max(map(len,x)) for x in zip(*li))
print '\n'.join(patform.format(*x) for x in li)
# OR
print
patform = '{{:<{}}} {{:<{}}} {{:<{}}}'.format( *tuple( max(map(len,x)) for x in zip(*li)) )
print '\n'.join(patform.format(*x) for x in li)
result
[['Something', 'Something else', 'Another thing'], ['Other things', 'More data', 'Element'], ['Stuff', 'data', 'etc']]
tuple( max(map(len,x)) for x in zip(*li)) == (12, 14, 13)
Something Something else Another thing
Other things More data Element
Stuff data etc
Something Something else Another thing
Other things More data Element
Stuff data etc
Something Something else Another thing
Other things More data Element
Stuff data etc
print '\n'.join([line+' ' for line in l])
精彩评论