开发者

Python: Split list into list of dicts?

开发者 https://www.devze.com 2022-12-14 21:09 出处:网络
Just beginning with python and know enough to know I know nothing. I would like to find alternative ways of splitting a list into a list of dicts. Example list:

Just beginning with python and know enough to know I know nothing. I would like to find alternative ways of splitting a list into a list of dicts. Example list:

data = ['ID:0:0:0',
        'Status:Ok',
        'Name:PhysicalDisk0:0:0',
        'State:Online',
        'FailurePredicted:No',
        'ID:0:0:1',
        'Status:Ok',
        'Name:PhysicalDisk0:0:1',
        'State:Online',
        'FailurePredicted:No']

Finished list of dicts:

[{'Status': 'Ok',
  'State': 'Online',
  'ID': '0:0:0',
  'FailurePredicted': 'No',
  'Name': 'Phys开发者_运维问答icalDisk0:0:0'},
 {'Status': 'Ok',
  'State': 'Online',
  'ID': '0:0:1',
  'Name': 'PhysicalDisk0:0:1',
  'FailurePredicted': 'No'}]

The list has repeating elements that require multiple dicts and the list varies in length. My code seems like it could be simplified, if only I knew Python better. My current code:

DELETED CODE It didn't work. :(

----------- File output as requested -------------------

# omreport storage pdisk controller=0
List of Physical Disks on Controller PERC 5/i Integrated (Embedded)

Controller PERC 5/i Integrated (Embedded)
ID                        : 0:0:0
Status                    : Ok
Name                      : Physical Disk 0:0:0
State                     : Online
Failure Predicted         : No
Progress                  : Not Applicable
Type                      : SAS
Capacity                  : 136.13 GB (146163105792 bytes)
Used RAID Disk Space      : 136.13 GB (146163105792 bytes)
Available RAID Disk Space : 0.00 GB (0 bytes)
Hot Spare                 : No
Vendor ID                 : DELL    
Product ID                : ST3146755SS     
Revision                  : T107
Serial No.                : 3LN1EF0G            
Negotiated Speed          : Not Available
Capable Speed             : Not Available
Manufacture Day           : 07
Manufacture Week          : 24
Manufacture Year          : 2005
SAS Address               : 5000C50004731C35

ID                        : 0:0:1
Status                    : Ok
Name                      : Physical Disk 0:0:1
State                     : Online
Failure Predicted         : No
Progress                  : Not Applicable
Type                      : SAS
Capacity                  : 136.13 GB (146163105792 bytes)
Used RAID Disk Space      : 136.13 GB (146163105792 bytes)
Available RAID Disk Space : 0.00 GB (0 bytes)
Hot Spare                 : No
Vendor ID                 : DELL    
Product ID                : ST3146755SS     
Revision                  : T107
Serial No.                : 3LN1EF88            
Negotiated Speed          : Not Available
Capable Speed             : Not Available
Manufacture Day           : 07
Manufacture Week          : 24
Manufacture Year          : 2005
SAS Address               : 5000C500047320B9


result = [{}]
for item in data:
    key, val = item.split(":", 1)
    if key in result[-1]:
        result.append({})
    result[-1][key] = val


If you have no more info than "each repetition of a key signals the need to start a new dict", your code can be improved only marginally, for example as:

results = []
curd = {}
for x in data:
  k, v = x.split(':', 1)
  if k in curd:
    results.append(curd)
    curd = {}
  curd[k] = v
results.append(curd)

i.e., no need to keep an intermediate list tmp rather than an intermediate dict curd. The semantics are subtly different -- you're initiating a new dict only when both key and value coincide (so an item such as 'Status:Borked' would "trample over" one being built from 'Status:Ok', for example), I'm taking the key only as the identifier (so, no trampling over in such a case) -- you sure the exact semantics you implement are what you require?


import re

results = []
temp = {}
for item in data:
    (key, value) = re.search('(.*?):(.*)', item).groups()
    if temp.has_key(key): temp = {}
    temp[key] = value
    if temp not in results: results.append(temp)


ret = []
ITEMS_AMOUNT = 5 
while True:
        tmp = {}
        for i in data[0:ITEMS_AMOUNT]:
                tmp.update(dict([i.split(':', 1)]))
        ret.append(tmp)

        if len(data) == ITEMS_AMOUNT:
                break
        data = data[ITEMS_AMOUNT:]

print ret 


d=dict([])
c=0
whatiwant=["ID","Status","Name","State","Failure Predicted"]
for line in open("file"):
    line=line.rstrip()
    sline=line.split(":",1)
    sline[0]=sline[0].strip()
    if sline[0]=="ID":
        c+=1
        d.setdefault(c,[])
    if sline[0] in whatiwant:
        d[c].append((sline[0],' '.join(sline[1:])))
for i,j in d.iteritems():
    print i,j

output

$ ./python.py
1 [('ID', ' 0:0:0'), ('Status', ' Ok'), ('Name', ' Physical Disk 0:0:0'), ('State', ' Online'), ('Failure Predicted', ' No')]
2 [('ID', ' 0:0:1'), ('Status', ' Ok'), ('Name', ' Physical Disk 0:0:1'), ('State', ' Online'), ('Failure Predicted', ' No')]
0

精彩评论

暂无评论...
验证码 换一张
取 消