简体   繁体   中英

Python 3.6 - Search word in a list that contain dictionary that containt dictionary in list

I tried to do a simple title but I'm a bit lost with this one.

I'm using a python module Python-HPILO in order to gather some information like Hard Drive Disk and DIMM details on HP Blades, this is working.

Example :

import hpilo
ilo = hpilo.Ilo('10.0.0.1', 'USER', 'PASSWORD')
health = ilo.get_embedded_health()
logical_drives = (health['storage']['Controller on System Board']['logical_drives'])
print(logical_drives)

Result (anonymized) :

[{**'label': '01', 'status': 'OK', 'capacity': '419 GiB', 'fault_tolerance': 'RAID 1/RAID 1+0', 'logical_drive_type': 'Data LUN', 'encryption_status': 'Not Encrypted', 'physical_drives': **[{**'label': 'Port 1I Box 1 Bay 1', 'status': 'OK', 'serial_number': 'SXXXXXXXX', 'model': 'YYYYYY', 'capacity': '419 GiB', **'marketing_capacity': '450 GB'**, 'location': 'Port 1I Box 1 Bay 1', 'fw_version': 'HPD9', 'drive_configuration': 'Configured', 'encryption_status': 'Not Encrypted', 'media_type': 'HDD'**}**, {'label': 'Port 1I Box 1 Bay 2', 'status': 'OK', 'serial_number': 'SXXXXXX', 'model': 'YYYYYY', 'capacity': '419 GiB', 'marketing_capacity': '450 GB', 'location': 'Port 1I Box 1 Bay 2', 'fw_version': 'HPD9', 'drive_configuration': 'Configured', 'encryption_status': 'Not Encrypted', 'media_type': 'HDD'**}]}]

I would like to collect the value of marketing_capacity, which is 450GB here. I found some other topics related to incursive search in list or dict but I were not able to make it work with this specific listed-dictonary-listed-dictonary thing.

Does anyone have a simple way/function to do research in this kind of list ?

You can access that variable by

logical_drives[0]['physical_drives'][0]['marketing_capacity']

'450 GB'


If the nesting of your dictionary changes you can unwrap both the lists and dictionaries in your list, and then extract the desired value

val = 'marketing_capacity'

def unwrap(dic):    
    temp = {}
    for i in dic:
        if type(i) in [list, dict]: temp.update(unwrap(i))
        elif type(dic[i]) in [list, dict]: temp.update(unwrap(dic[i]))
        else: temp.update({i: dic[i]})
    return temp

temp = [{'label': '01', 'status': 'OK', 'capacity': '419 GiB', 'fault_tolerance': 'RAID 1/RAID 1+0', 'logical_drive_type': 'Data LUN', 'encryption_status': 'Not Encrypted', 'physical_drives': [{'label': 'Port 1I Box 1 Bay 1', 'status': 'OK', 'serial_number': 'SXXXXXXXX', 'model': 'YYYYYY', 'capacity': '419 GiB', 'marketing_capacity': '450 GB', 'location': 'Port 1I Box 1 Bay 1', 'fw_version': 'HPD9', 'drive_configuration': 'Configured', 'encryption_status': 'Not Encrypted', 'media_type': 'HDD'}, {'label': 'Port 1I Box 1 Bay 2', 'status': 'OK', 'serial_number': 'SXXXXXX', 'model': 'YYYYYY', 'capacity': '419 GiB', 'marketing_capacity': '450 GB', 'location': 'Port 1I Box 1 Bay 2', 'fw_version': 'HPD9', 'drive_configuration': 'Configured', 'encryption_status': 'Not Encrypted', 'media_type': 'HDD'}]}]
x = unwrap(temp)
x['marketing_capacity']

There's nothing special about dictionaries in lists. You already know how to look up nested values - just continue the same principle.

print(logical_drives[0]['physical_drives'][0]['marketing_capacity'])

Try this

import hpilo
ilo = hpilo.Ilo('10.0.0.1', 'USER', 'PASSWORD')
health = ilo.get_embedded_health()
logical_drives = (logical_drives[0]['physical_drives'][0]['marketing_capacity'])
print(logical_drives)

Just loop through it like any other list:

drive_data =  health['storage']['Controller on System Board']['logical_drives']

for logical_drive in drive_data:
    for physical_drive in logical_drive['physical_drives']:
       print(physical_drive['marketing_capacity'])

To get all values for 'marketing_capacity' I would use a generic list comprehension.

lst = [{'label': '01', 'status': 'OK', 'capacity': '419 GiB', 'fault_tolerance': 'RAID 1/RAID 1+0', 'logical_drive_type': 'Data LUN', 'encryption_status': 'Not Encrypted', 'physical_drives': [{'label': 'Port 1I Box 1 Bay 1', 'status': 'OK', 'serial_number': 'SXXXXXXXX', 'model': 'YYYYYY', 'capacity': '419 GiB', 'marketing_capacity': '450 GB', 'location': 'Port 1I Box 1 Bay 1', 'fw_version': 'HPD9', 'drive_configuration': 'Configured', 'encryption_status': 'Not Encrypted', 'media_type': 'HDD'}, {'label': 'Port 1I Box 1 Bay 2', 'status': 'OK', 'serial_number': 'SXXXXXX', 'model': 'YYYYYY', 'capacity': '419 GiB', 'marketing_capacity': '450 GB', 'location': 'Port 1I Box 1 Bay 2', 'fw_version': 'HPD9', 'drive_configuration': 'Configured', 'encryption_status': 'Not Encrypted', 'media_type': 'HDD'}]}]

res = [d2.get('marketing_capacity') for d2 in d.get('physical_drives') for d in lst]

# ['450 GB', '450 GB']

Note this will work for arbitrary dictionaries in your outer list, as well as arbitrary dictionaries in your inner list.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM