问题
I getting data from subprocess command as a string. I want to store this data in a dict. How best do I achieve this?
Here is data example: (I have returned this as a string from subprocess.)
NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
loop0 7:0 0 140.7M 1 loop /snap/gnome-3-26-1604/82
loop1 7:1 0 89.3M 1 loop /snap/core/6673
sda 8:0 0 11G 0 disk
├─sda1 8:1 0 10.9G 0 part /
├─sda14 8:14 0 4M 0 part
└─sda15 8:15 0 106M 0 part /boot/efi
Here is the output I want:
{block device 1:
{ "name" : value,
"maj:min" : value,
"RM" : value,
"SIZE" : value,
"RO": value,
"TYPE": value,
"MOUNTPOINT" : value},
block device 2:
{ "name" : value,
"maj:min" : value,
"RM" : value,
"SIZE" : value,
"RO": value,
"TYPE": value,
"MOUNTPOINT" : value},
...
}
Here is the method I am trying to implement to sort this data
def multiple_column_dict(a_string):
a_dict = {}
lines = re.split("\n", a_string)
for l in lines:
l = re.split(" +", l)
a_dict = dict(zip(l[::2], l[1::2]))
return a_dict
Note 1: I know that the zip method is incorrect
Note 2: I don't know how to account for items that are - e.g. when '\n' comes in after 'disk'.
回答1:
Using itertools.zip_longest
--> If using python2 izip_longest
Ex:
from itertools import zip_longest
data = """NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
loop0 7:0 0 140.7M 1 loop /snap/gnome-3-26-1604/82
loop1 7:1 0 89.3M 1 loop /snap/core/6673
sda 8:0 0 11G 0 disk
├─sda1 8:1 0 10.9G 0 part /
├─sda14 8:14 0 4M 0 part
└─sda15 8:15 0 106M 0 part /boot/efi"""
result = []
header = None
for line in data.splitlines():
line = line.strip().split()
if not header:
header = line
else:
result.append(dict(zip_longest(header, line, fillvalue="")))
Output:
{'NAME': 'loop0', 'MAJ:MIN': '7:0', 'RM': '0', 'SIZE': '140.7M', 'RO': '1', 'TYPE': 'loop', 'MOUNTPOINT': '/snap/gnome-3-26-1604/82'}
{'NAME': 'loop1', 'MAJ:MIN': '7:1', 'RM': '0', 'SIZE': '89.3M', 'RO': '1', 'TYPE': 'loop', 'MOUNTPOINT': '/snap/core/6673'}
{'NAME': 'sda', 'MAJ:MIN': '8:0', 'RM': '0', 'SIZE': '11G', 'RO': '0', 'TYPE': 'disk', 'MOUNTPOINT': ''}
{'NAME': '├─sda1', 'MAJ:MIN': '8:1', 'RM': '0', 'SIZE': '10.9G', 'RO': '0', 'TYPE': 'part', 'MOUNTPOINT': '/'}
{'NAME': '├─sda14', 'MAJ:MIN': '8:14', 'RM': '0', 'SIZE': '4M', 'RO': '0', 'TYPE': 'part', 'MOUNTPOINT': ''}
{'NAME': '└─sda15', 'MAJ:MIN': '8:15', 'RM': '0', 'SIZE': '106M', 'RO': '0', 'TYPE': 'part', 'MOUNTPOINT': '/boot/efi'}
Edit as per comment
from itertools import zip_longest
data = """NAME MAJ:MIN RM SIZE RO TYPE MOUNTPOINT
loop0 7:0 0 140.7M 1 loop /snap/gnome-3-26-1604/82
loop1 7:1 0 89.3M 1 loop /snap/core/6673
sda 8:0 0 11G 0 disk
├─sda1 8:1 0 10.9G 0 part /
├─sda14 8:14 0 4M 0 part
└─sda15 8:15 0 106M 0 part /boot/efi"""
result = {}
header = None
c = 1
for line in data.splitlines():
line = line.strip().split()
if not header:
header = line
else:
key = "block device {}".format(c)
result.update({key: dict(zip_longest(header, line, fillvalue=""))})
c += 1
print(result)
Output:
{'block device 1': {'MAJ:MIN': '7:0',
'MOUNTPOINT': '/snap/gnome-3-26-1604/82',
'NAME': 'loop0',
'RM': '0',
'RO': '1',
'SIZE': '140.7M',
'TYPE': 'loop'},
'block device 2': {'MAJ:MIN': '7:1',
'MOUNTPOINT': '/snap/core/6673',
'NAME': 'loop1',
'RM': '0',
'RO': '1',
'SIZE': '89.3M',
'TYPE': 'loop'},
'block device 3': {'MAJ:MIN': '8:0',
'MOUNTPOINT': '',
'NAME': 'sda',
'RM': '0',
'RO': '0',
'SIZE': '11G',
'TYPE': 'disk'},
'block device 4': {'MAJ:MIN': '8:1',
'MOUNTPOINT': '/',
'NAME': '├─sda1',
'RM': '0',
'RO': '0',
'SIZE': '10.9G',
'TYPE': 'part'},
'block device 5': {'MAJ:MIN': '8:14',
'MOUNTPOINT': '',
'NAME': '├─sda14',
'RM': '0',
'RO': '0',
'SIZE': '4M',
'TYPE': 'part'},
'block device 6': {'MAJ:MIN': '8:15',
'MOUNTPOINT': '/boot/efi',
'NAME': '└─sda15',
'RM': '0',
'RO': '0',
'SIZE': '106M',
'TYPE': 'part'}}
来源:https://stackoverflow.com/questions/57003873/python-convert-table-to-string-to-keyvalue-pairs-and-store-in-dict