Home > database >  How to print out nicely formatted tables from a dictionary
How to print out nicely formatted tables from a dictionary

Time:10-05

For the sake of practicing how to be more comfortable and fluent in working with dictionaries, I have written a little program that reads the content of a file and adds it to a dictionary as a key: value pair. This is no problem, but when I got curious about how to print the content out again in the same format as the table in the datafile using for-loops, I ran into trouble.

My question is: How can I print out the content of the dictionary onto the terminal using for-loops?

The datafile is:

Name    Age     School
Anne    10      Eiksmarka
Tom     15      Marienlyst
Vidar   18      Persbråten
Ayla    18      Kongshavn
Johanne 17      Wang
Silje   16      Eikeli
Per     19      UiO
Ali     25      NTNU

My code is:

infile = open("table.dat", "r")
data = {}

headers = infile.readline().split()
for i in range(len(headers)):
    data[headers[i]] = []

for line in infile:
    words = line.split()
    for i in range(len(headers)):
        data[headers[i]].append(words[i])
infile.close()

I would like the out print the data back onto the terminal. Ideally, the out print should look something like this

Name    Age     School
Anne    10      Eiksmarka
Tom     15      Marienlyst
Vidar   18      Persbråten
Ayla    18      Kongshavn
Johanne 17      Wang
Silje   16      Eikeli
Per     19      UiO
Ali     25      NTNU

If someone can help me with this, I would be grateful.

CodePudding user response:

Take look at .ljust, .rjust and .center methods of str, consider following simple example

d = {"Alpha": 1, "Beta": 10, "Gamma": 100, "ExcessivelyLongName": 1}
for key, value in d.items():
    print(key.ljust(5), str(value).rjust(3))

output

Alpha   1
Beta   10
Gamma 100
ExcessivelyLongName   1

Note that ljust does add (by default) space to attain specified width or do nothing if name is longer than that, also as values are integers they need to be first converted to str if you want to use one of mentioned methods.

CodePudding user response:

The easiest solution is to use a library such as Tabulate, which you can find here an example of an output (You can customize it further)

>>> from tabulate import tabulate

>>> table = [["Sun",696000,1989100000],["Earth",6371,5973.6],
...          ["Moon",1737,73.5],["Mars",3390,641.85]]
>>> print(tabulate(table))
-----  ------  -------------
Sun    696000     1.9891e 09
Earth    6371  5973.6
Moon     1737    73.5
Mars     3390   641.85
-----  ------  -------------

Otherwise, if you MUST use your own custom for-loop, you can add tabs to fix how it looks as in:

print(a "\t") where \t is the horizental tabulation escape character

Edit: An example of how this can be utilized is below:

infile = open("table.dat", "r")
data = {}

headers = infile.readline().split()
for i in range(len(headers)):
    data[headers[i]] = []

for line in infile:
    words = line.split()
    for i in range(len(headers)):
        data[headers[i]].append(words[i])
        print(words[i],end= '\t')
    print()
infile.close()

Things to note:

1- For each field, we use print(...,end= '\t'), this causes the output to be a tab instead of a new line, we also might consider adding more tabs (e.g. end='\t\t') or spaces, or any other formating such as a seperator character (e.g. `end='\t|\t')

2- After each line, we use print(), this will only print a new line, moving the cursor for the printing downwards.

CodePudding user response:

You can do this using pandas although it isn't exactly your same styling:

import pandas as pd

with open('filename.csv') as f:
    headers, *data = map(str.split, f.readlines())

df = pd.DataFrame(dict(zip(headers, zip(*data)))

print(df.to_string(index=False))

   Name Age     School
   Anne  10  Eiksmarka
    Tom  15 Marienlyst
  Vidar  18 Persbråten
   Ayla  18  Kongshavn
Johanne  17       Wang
  Silje  16     Eikeli
    Per  19        UiO
    Ali  25       NTNU
  • Related