Python Forum
format the output from a nested dictionary. - Printable Version

+- Python Forum (https://python-forum.io)
+-- Forum: Python Coding (https://python-forum.io/forum-7.html)
+--- Forum: General Coding Help (https://python-forum.io/forum-8.html)
+--- Thread: format the output from a nested dictionary. (/thread-33534.html)



format the output from a nested dictionary. - nostradamus64 - May-02-2021

Hello everyone im trying to make my codes output to look like this output,
without any trailing or leading symbols. Any tips on how i can do that?

The expected output should look like this.

Output:
| 0 | root | /bin/bash | 1 | bin | /usr/bin/nologin | 2 | daemon | /usr/bin/nologin | 1000 | nsa | /bin/bash
currentuser ={'root':{'uid': 0,'username': 'root' ,'shell': '/bin/bash'},
        'daemon': {'uid': 1,'username': 'daemon' ,'shell': '/usr/sbin/nologin'},
        'bin': {'uid': 2,'username': 'bin', 'shell':'/usr/sbin/nologin'},
        'nsa': {'uid': 1000,'username': 'nsa', 'shell': '/bin/bash'}}

for key, value in currentuser.items():
print(f"\nKey: {key}")
print(f"Value: {value}")



RE: format the output from a nested dictionary. - menator01 - May-02-2021

currentuser ={'root':{'uid': 0,'username': 'root' ,'shell': '/bin/bash'},
'daemon': {'uid': 1,'username': 'daemon' ,'shell': '/usr/sbin/nologin'},
'bin': {'uid': 2,'username': 'bin', 'shell':'/usr/sbin/nologin'},
'nsa': {'uid': 1000,'username': 'nsa', 'shell': '/bin/bash'}}

for v in currentuser.values():
    print(f'|{v["uid"]}|{v["username"]}|{v["shell"]}')
Output:
|0|root|/bin/bash |1|daemon|/usr/sbin/nologin |2|bin|/usr/sbin/nologin |1000|nsa|/bin/bash



RE: format the output from a nested dictionary. - bowlofred - May-03-2021

If you want formatting, I prefer using a formatting package. tabulate has worked well for me.

from tabulate import tabulate

currentuser ={'root':{'uid': 0,'username': 'root' ,'shell': '/bin/bash'},
        'daemon': {'uid': 1,'username': 'daemon' ,'shell': '/usr/sbin/nologin'},
        'bin': {'uid': 2,'username': 'bin', 'shell':'/usr/sbin/nologin'},
        'nsa': {'uid': 1000,'username': 'nsa', 'shell': '/bin/bash'}}


columns = list(next(iter(currentuser.values())).keys())
print(tabulate([x.values() for x in currentuser.values()], headers=columns, tablefmt="presto"))
Output:
uid | username | shell -------+------------+------------------- 0 | root | /bin/bash 1 | daemon | /usr/sbin/nologin 2 | bin | /usr/sbin/nologin 1000 | nsa | /bin/bash



RE: format the output from a nested dictionary. - nostradamus64 - May-03-2021

(May-02-2021, 11:19 PM)menator01 Wrote:
currentuser ={'root':{'uid': 0,'username': 'root' ,'shell': '/bin/bash'},
'daemon': {'uid': 1,'username': 'daemon' ,'shell': '/usr/sbin/nologin'},
'bin': {'uid': 2,'username': 'bin', 'shell':'/usr/sbin/nologin'},
'nsa': {'uid': 1000,'username': 'nsa', 'shell': '/bin/bash'}}

for v in currentuser.values():
    print(f'|{v["uid"]}|{v["username"]}|{v["shell"]}')
Output:
|0|root|/bin/bash |1|daemon|/usr/sbin/nologin |2|bin|/usr/sbin/nologin |1000|nsa|/bin/bash

Thanks for the reply i appreciate it. It works fine,
but i want this symbol | in the columns to align with eachother.


RE: format the output from a nested dictionary. - nostradamus64 - May-03-2021

(May-03-2021, 01:54 AM)bowlofred Wrote: If you want formatting, I prefer using a formatting package. tabulate has worked well for me.

from tabulate import tabulate

currentuser ={'root':{'uid': 0,'username': 'root' ,'shell': '/bin/bash'},
        'daemon': {'uid': 1,'username': 'daemon' ,'shell': '/usr/sbin/nologin'},
        'bin': {'uid': 2,'username': 'bin', 'shell':'/usr/sbin/nologin'},
        'nsa': {'uid': 1000,'username': 'nsa', 'shell': '/bin/bash'}}


columns = list(next(iter(currentuser.values())).keys())
print(tabulate([x.values() for x in currentuser.values()], headers=columns, tablefmt="presto"))
Output:
uid | username | shell -------+------------+------------------- 0 | root | /bin/bash 1 | daemon | /usr/sbin/nologin 2 | bin | /usr/sbin/nologin 1000 | nsa | /bin/bash

Thanks for the reply appreciate it, but i want to do it without import,
and i want the output to look like i requested.


RE: format the output from a nested dictionary. - bowlofred - May-03-2021

If you don't want to import, then you'll have to code it up.

Use len(str) to find the length of each of the elements in each column. Then use format strings to print each of the elements from that column in the correct length.

formats = ["<20", 10, 5]
data = [15, "Hello", "/bin/sh"]

print("".join(f"| {d:{f}}" for d,f in zip(data,formats)))
Output:
| 15 | Hello | /bin/sh



RE: format the output from a nested dictionary. - perfringo - May-03-2021

You can pass formatting with f-strings so little adjustment to menator01 code would deliver required result (numbers are aligned to right and text to left which is canonical way to display these datatypes in table style):

currentuser ={'root':{'uid': 0,'username': 'root' ,'shell': '/bin/bash'},
              'daemon': {'uid': 1,'username': 'daemon' ,'shell': '/usr/sbin/nologin'},
              'bin': {'uid': 2,'username': 'bin', 'shell':'/usr/sbin/nologin'},
              'nsa': {'uid': 1000,'username': 'nsa', 'shell': '/bin/bash'}}

for value in currentuser.values():
    print(f"{value['uid']:>8} {value['username']:<12} {value['shell']:<15}")
This will print:

Output:
0 root /bin/bash 1 daemon /usr/sbin/nologin 2 bin /usr/sbin/nologin 1000 nsa /bin/bash
I personally like this type of display better than separated with |. However, if you prefer that you can add these into f-string quite easily:

for value in currentuser.values():
    print(f"| {value['uid']:>8} | {value['username']:<12} | {value['shell']:<15}")
This will deliver:

Output:
| 0 | root | /bin/bash | 1 | daemon | /usr/sbin/nologin | 2 | bin | /usr/sbin/nologin | 1000 | nsa | /bin/bash



RE: format the output from a nested dictionary. - menator01 - May-03-2021

Another possibility
currentuser ={'root':{'uid': 0,'username': 'root' ,'shell': '/bin/bash'},
'daemon': {'uid': 1,'username': 'daemon' ,'shell': '/usr/sbin/nologin'},
'bin': {'uid': 2,'username': 'bin', 'shell':'/usr/sbin/nologin'},
'nsa': {'uid': 1000,'username': 'nsa', 'shell': '/bin/bash'}}

for v in currentuser.values():
    print(f'|{v["uid"]}{" ".rjust(10-len(str(v["uid"])))}|{v["username"]}{" ".rjust(10-len(v["username"]))}|{v["shell"]}')
Output:
|0 |root |/bin/bash |1 |daemon |/usr/sbin/nologin |2 |bin |/usr/sbin/nologin |1000 |nsa |/bin/bash



RE: format the output from a nested dictionary. - nostradamus64 - May-03-2021

(May-03-2021, 07:50 AM)perfringo Wrote: You can pass formatting with f-strings so little adjustment to menator01 code would deliver required result (numbers are aligned to right and text to left which is canonical way to display these datatypes in table style):

currentuser ={'root':{'uid': 0,'username': 'root' ,'shell': '/bin/bash'},
              'daemon': {'uid': 1,'username': 'daemon' ,'shell': '/usr/sbin/nologin'},
              'bin': {'uid': 2,'username': 'bin', 'shell':'/usr/sbin/nologin'},
              'nsa': {'uid': 1000,'username': 'nsa', 'shell': '/bin/bash'}}

for value in currentuser.values():
    print(f"{value['uid']:>8} {value['username']:<12} {value['shell']:<15}")
This will print:

Output:
0 root /bin/bash 1 daemon /usr/sbin/nologin 2 bin /usr/sbin/nologin 1000 nsa /bin/bash
I personally like this type of display better than separated with |. However, if you prefer that you can add these into f-string quite easily:

for value in currentuser.values():
    print(f"| {value['uid']:>8} | {value['username']:<12} | {value['shell']:<15}")
This will deliver:

Output:
| 0 | root | /bin/bash | 1 | daemon | /usr/sbin/nologin | 2 | bin | /usr/sbin/nologin | 1000 | nsa | /bin/bash

Thank you this worked well!


RE: format the output from a nested dictionary. - nostradamus64 - May-03-2021

Thank you all for your replies, the output is as i wanted it to print out.