Reputation: 4122
I have a nested containing values of different lengths as so:
[['cat', 123, 'yellow'],
['dog', 12345, 'green'],
[horse', 123456, 'red']]
I want to print them like this:
cat, 123, yellow
dog, 12345, green
horse, 123456, red
I have tried using pprint to achieve my aims with the following code:
for sub in master_list:
pp = pprint.PrettyPrinter(indent=4)
pp.pprint(sub)
Where master is the nested list and sub the lists within it. This however gives me an output like so:
[
'cat',
123,
'yellow'
],
[
'dog',
12345,
'green'
],
[
horse',
123456,
'red'
]
Is there a python module that allows me to relatively easily achieving what I want, without some sort of convoluted hack?
Thanks
Upvotes: 2
Views: 2024
Reputation: 11183
Another way, given the nested list:
table = [['cat', 123, 'yellow'],
['dog', 12345, 'green'],
['horse', 123456, 'red']]
Using string methods:
for line in table:
print("|", end='')
for word in line:
print (f" {word}".ljust(10) + "|", end='')
print()
To get:
| cat | 123 | yellow |
| dog | 12345 | green |
| horse | 123456 | red |
Upvotes: 0
Reputation: 13858
You can do this:
spacing = [max(map(lambda x: len(str(x)), d)) for d in zip(*data)]
for row in data:
for i, elem in enumerate(row):
e = str(elem) + (',' if i < len(row) -1 else '')
print('{{:{}}} '.format(spacing[i]+1).format(e), end='')
print()
cat, 123, orange
elephant, 500000, green
horse, 123456.0, red
spacing
is defined by first gathering the maximum lengths of each "column" in your data. We can group the columns by using:
zip(*data)
Which gives a transposed copy of your data like this:
('cat', 'elephant', 'horse'),
(123, 500000, 123456.0),
('orange', 'green', 'red')
Then we use the map
function to apply the len(str(x))
function over these columns:
(3, 8, 5),
(3, 6, 8),
(6, 5, 3)
Then we just get the max
of each column, combine everything in a list comprehension and return it as spacing
:
spacing = [max(map(lambda x: len(str(x)), d)) for d in zip(*data)]
Then, while we loop through your data, we want to also enumerate(row)
so we know which "column" we're working with. i
will give you the index of the column in addition to the actual elem
.
After that, we assign a temporary str
to append the comma if it's not the last element:
e = str(elem) + (',' if i < len(row) -1 else '')
This makes it a bit more readable then adding it as part of the format params.
Afterwards we use string formatting (or e.ljust(spacing[i] + 1)
if you wish) to add the predefined maximum spacing
based on the column. Note we format the string twice by first escaping the outer curly brackets ({{
and }}
), so it can be in sequence:
'{{:{}}}.format(9).format(e)
# becomes
'{:9}'.format(e)
# becomes
'cat, '
Note the use of end=''
to make the print line continuous until the row
has finished. The spacing[i] + 1
is to account for the added comma.
I must confess this might not be the most efficient way, but depending on what you're trying to achieve the solution can be markedly different.
Upvotes: 1
Reputation: 2224
You may use the following code:
myLst = [['cat', 123, 'yellow'],
['dog', 12345, 'green'],
['horse', 123456, 'red']]
for subLst in myLst:
print("\t".join([str(ele) for ele in subLst]))
Which is printing the output like so:
cat 123 yellow
dog 12345 green
horse 123456 red
In case you want to have "," too, just change the line
print("\t".join([str(ele) for ele in subLst]))
to
print(",\t".join([str(ele) for ele in subLst]))
And the complete thing as a one-liner:
print("\n".join([",\t".join([str(ele) for ele in subLst]) for subLst in myLst]))
Or in case you need a function:
def printLst(myLst):
print("\n".join([",\t".join([str(ele) for ele in subLst]) for subLst in myLst]))
Edit
As pointed out in the comments this is also a good use-case for the python map
function. Which can be used in order to make everything shorter ;)
Upvotes: 2
Reputation: 902
You can use this:
a = [['cat', 123, 'yellow'], ['dog', 12345, 'green'], ['horse', 123456, 'red']]
# Get the max length of string in the list
m = max([len(str(x)) for y in a for x in y])
# Use the format specifier in Python print function:
# Example: print '{:10s} {:3d} {:7.2f}'.format('xxx', 123, 98)
# This prints : xxx 123 98.00
# We will create the string as {:6s}, here 6 is the length in our case and will be generated dynamically using 'm'
list(map(lambda x: print('\t'.join(list(map(lambda y: str('{' + ':{m}s'.format(m=m) +'}').format(str(y)), x)))), a))
Output:
cat 123 yellow
dog 12345 green
horse 123456 red
Upvotes: 0
Reputation: 51643
Your concrete format wishescan be solved by printing with ljust
to add the needed spaces:
data = [['cat', 123, 'yellow'],
['dog', 12345, 'green'],
['horse', 123456, 'red']]
# get the overall widest string as base for right-aligning them
max_len = max( len(str(x)) for k in data for x in k)
for inner in data:
first = True
for elem in inner[:-1]: # all but the last
text = "{},".format(elem).ljust(max_len+2)
print(text,end="")
print(inner[-1]) # print last
Output:
cat, 123, yellow
dog, 12345, green
horse, 123456, red
Doku:
Generally for formatting you can use the string format mini language to format your output to your liking:
for inner in data:
first = True
for elem in inner:
if first:
text = "{:<{}} ".format(elem,max_len+2)
first = False
else:
text = ", {:<{}} ".format(elem,max_len+2)
print(text, end="")
print("")
Output:
cat , 123 , yellow
dog , 12345 , green
horse , 123456 , red
The format string "{:<{}} ".format(elem,max_len+2)
formats element
rightaligned into max_len+2
characters. The first
thing is just to make your ,
not appear on the start of the line.
Upvotes: 1
Reputation: 1824
Pandas can help.
import pandas as pd
lst = [['cat', 123, 'yellow'], ['dog', 12345, 'green'], ['horse', 123456, 'red']]
df = pd.DataFrame(lst)
print(df)
Output:
0 1 2
0 cat 123 yellow
1 dog 12345 green
2 horse 123456 red
Upvotes: 2