Python: разбить список на список диктов? - PullRequest
3 голосов
/ 23 декабря 2009

Просто начинаю с python и знаю достаточно, чтобы знать, что я ничего не знаю. Я хотел бы найти альтернативные способы разделения списка на список диктовок. Пример списка:

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']

Готовый список диктов:

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

В списке есть повторяющиеся элементы, требующие нескольких диктов, и список может быть разной длины. Мой код, кажется, можно было бы упростить, если бы я знал Python лучше. Мой текущий код:

УДАЛЕННЫЙ КОД Не сработало. (

----------- 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

Ответы [ 5 ]

8 голосов
/ 23 декабря 2009
result = [{}]
for item in data:
    key, val = item.split(":", 1)
    if key in result[-1]:
        result.append({})
    result[-1][key] = val
1 голос
/ 23 декабря 2009

Если у вас нет больше информации, чем «каждое повторение клавиши сигнализирует о необходимости начать новый дикт», ваш код может быть улучшен лишь незначительно, например:

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)

т.е. нет необходимости вести промежуточный список tmp, а не промежуточный дикт curd. Семантика немного отличается - вы инициируете новый dict только тогда, когда и ключ, и значение совпадают (поэтому такой элемент, как 'Status:Borked', может «растоптать» элемент, созданный, например, из 'Status:Ok'), я принимая ключ только в качестве идентификатора (то есть, в таком случае не попирая) - вы уверены точная семантика, которую вы используете, - это то, что вам нужно?

1 голос
/ 23 декабря 2009
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)
0 голосов
/ 23 декабря 2009
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

выход

$ ./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 голосов
/ 23 декабря 2009
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 
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...