Python - 迭代列表和词典

时间:2014-03-21 01:31:24

标签: python list

您好,我正在重新发布此问题,但提供了有关我要实现的内容的更多信息。在过去的几天里,它一直让我发疯,我似乎无法取得进展。基本上,我有这个数据结构:

data_in =\
{'map': {'command_line': u'command goes here',
         'scaninfo': {u'tcp': {'method': u'syn', 'services': u'80,443'}},
         'stats': {'downhosts': u'0',
                   'elapsed': u'1.71',
                   'timestr': u'Thu Mar 20 18:18:09 2014',
                   'totalhosts': u'3',
                   'uphosts': u'3'}},
 'scan': {u'2a00:2384:0:208f::13': {'addresses': {u'ipv6': u'2a00:2384:0:f467::13',
                                                  u'mac': u'00:gf:88:9:56:D5'},
                                    'hostname': u'static.abc.com',
                                    'status': {'reason': u'nd-response',
                                               'state': u'up'},
                                    u'tcp': {80: {'conf': u'3',
                                                  'cpe': '',
                                                  'extrainfo': '',
                                                  'name': u'http',
                                                  'product': '',
                                                  'reason': u'syn-ack',
                                                  'state': u'open',
                                                  'version': ''},
                                             443: {'conf': u'3',
                                                   'cpe': '',
                                                   'extrainfo': '',
                                                   'name': u'https',
                                                   'product': '',
                                                   'reason': u'syn-ack',
                                                   'script': {u'ssl-cert': u'place holder'},
                                                   'state': u'open',
                                                   'version': ''}},
                                    'vendor': {u'00:0C:29:7C:13:D3': u'VMware'}},
          u'2a00:2384:0:208f::15': {'addresses': {u'ipv6': u'a848:2384:0:3456::15',
                                                  u'mac': u'00:gf:29:99:6D:96'},
                                    'hostname': u'static.xyz.com',
                                    'status': {'reason': u'nd-response',
                                               'state': u'up'},
                                    u'tcp': {80: {'conf': u'3',
                                                  'cpe': '',
                                                  'extrainfo': '',
                                                  'name': u'http',
                                                  'product': '',
                                                  'reason': u'syn-ack',
                                                  'state': u'open',
                                                  'version': ''},
                                             443: {'conf': u'3',
                                                   'cpe': '',
                                                   'extrainfo': '',
                                                   'name': u'https',
                                                   'product': '',
                                                   'reason': u'syn-ack',
                                                   'script': {u'ssl-cert': u'place holder'},
                                                   'state': u'open',
                                                   'version': ''}},
                                    'vendor': {u'00:0C:67:99:6f:96': u'VMware'}},
          u'2a00:2384:0:208f::16': {'addresses': {u'ipv6': u'8938:8584:0:8685::16',
                                                  u'mac': u'00:54:29:fg:55:0F'},
                                    'hostname': u'static.edf.com',
                                    'status': {'reason': u'nd-response',
                                               'state': u'up'},
                                    u'tcp': {80: {'conf': u'3',
                                                  'cpe': '',
                                                  'extrainfo': '',
                                                  'name': u'http',
                                                  'product': '',
                                                  'reason': u'syn-ack',
                                                  'state': u'open',
                                                  'version': ''},
                                             443: {'conf': u'3',
                                                   'cpe': '',
                                                   'extrainfo': '',
                                                   'name': u'https',
                                                   'product': '',
                                                   'reason': u'syn-ack',
                                                   'script': {u'ssl-cert': u'place holder'},
                                                   'state': u'open',
                                                   'version': ''}},
                                    'vendor': {u'00:0C:55:AE:33:ff': u'VMware'}}}}

需要创建一个如下所示的简化版本:

data_out =\
[{'address': u'2a00:2384:0:208f::13',
  'hostname': u'static.bt.com',
  'ports': [{80: {'reason': u'syn-ack', 'state': u'open'}},
            {443: {'reason': u'syn-ack',
                   'ssl_cert': u'place   holder',
                   'state': u'open'}}]}]

根据@jonrsharpe之前的建议,我创建了一个帮助函数,使我能够找到键。这证明是有帮助的,但我仍然在努力获得理想的结果。

def find_key(data, search_key, out=None):
"""Find all values from a nested dictionary for a given key."""
if out is None:
    out = []
if isinstance(data, dict):
    if search_key in data:
        out.append(data[search_key])
    for key in data:
        find_key(data[key], search_key, out)
return out

这里真的很感激任何帮助!

1 个答案:

答案 0 :(得分:0)

这并不是那么难;你只需要查看导致你想要的数据结构 - 这会因为格式不佳而变得更加困难,所以我重新缩进你的输入并标记了键(<==)和字段({ {1}})你正在寻找:

!!!

同样适用于您想要的输出(经适当调整):

data_in = {
    'map': {
        'stats': {
            'uphosts': u'3',
            'timestr': u'Thu Mar 20 18:18:09 2014',
            'downhosts': u'0',
            'totalhosts': u'3',
            'elapsed': u'1.71'
        },
        'scaninfo': {
            u'tcp': {
                'services': u'80,443',
                'method': u'syn'
            }
        },
        'command_line': u'command goes here'
    },
    'scan': {                           # <==
        u'2a00:2384:0:208f::13': {          # <== !!!
            'status': {
                'state': u'up',
                'reason': u'nd-response'
            },
            'hostname': u'static.abc.com',      # !!!
            'vendor': {
                u'00:0C:29:7C:13:D3': u'VMware'
            },
            'addresses': {
                u'mac': u'00:gf:88:9:56:D5',
                u'ipv6': u'2a00:2384:0:f467::13'
            },
            u'tcp': {                       # <==
                80: {                       # <== !!!
                    'product': '',
                    'state': u'open',           # !!!
                    'version': '',
                    'name': u'http',
                    'conf': u'3',
                    'extrainfo': '',
                    'reason': u'syn-ack',       # !!!
                    'cpe': ''
                },
                443: {                      # <== !!!
                    'product': '',
                    'state': u'open',           # !!!
                    'version': '',
                    'name': u'https',
                    'conf': u'3',
                    'script': {             # <==
                        u'ssl-cert': u'place holder'  # !!!
                    },
                    'extrainfo': '',
                    'reason': u'syn-ack',       # !!!
                    'cpe': ''
                }
            }
        },
        u'2a00:2384:0:208f::15': {
            'status': {
                'state': u'up',
                'reason': u'nd-response'
            },
            'hostname': u'static.xyz.com',
            'vendor': {
                u'00:0C:67:99:6f:96': u'VMware'
            },
            'addresses': {
                u'mac': u'00:gf:29:99:6D:96',
                u'ipv6': u'a848:2384:0:3456::15'
            },
            u'tcp': {
                80: {
                    'product': '',
                    'state': u'open',
                    'version': '',
                    'name': u'http',
                    'conf': u'3',
                    'extrainfo': '',
                    'reason': u'syn-ack',
                    'cpe': ''
                },
                443: {
                    'product': '',
                    'state': u'open',
                    'version': '',
                    'name': u'https',
                    'conf': u'3',
                    'script': {
                        u'ssl-cert': u'place holder'
                    },
                    'extrainfo': '',
                    'reason': u'syn-ack',
                    'cpe': ''
                }
            }
        },
        u'2a00:2384:0:208f::16': {
            'status': {
                'state': u'up',
                'reason': u'nd-response'
            },
            'hostname': u'static.edf.com',
            'vendor': {
                u'00:0C:55:AE:33:ff': u'VMware'
            },
            'addresses': {
                u'mac': u'00:54:29:fg:55:0F',
                u'ipv6': u'8938:8584:0:8685::16'
            },
            u'tcp': {
                80: {
                    'product': '',
                    'state': u'open',
                    'version': '',
                    'name': u'http',
                    'conf': u'3',
                    'extrainfo': '',
                    'reason': u'syn-ack',
                    'cpe': ''
                },
                443: {
                    'product': '',
                    'state': u'open',
                    'version': '',
                    'name': u'https',
                    'conf': u'3',
                    'script': {
                        u'ssl-cert': u'place holder'
                    },
                    'extrainfo': '',
                    'reason': u'syn-ack',
                    'cpe': ''
                }
            }
        }
    }
}

然后提取变为:

data_out = [
    {
        'address': u'2a00:2384:0:208f::13',
        'hostname': u'static.bt.com',
        'ports': {
            80: {
                'state': u'open',
                'reason': u'syn-ack'
            },
            443: {
                'ssl_cert': u'place   holder',
                'state': u'open',
                'reason': u'syn-ack'
            }
        }
    }
]

导致所需的输出,

def remap_port(port, port_data):
    result = {
        "state":  port_data["state"],
        "reason": port_data["reason"]
    }
    try:
        result["ssl_cert"] = port_data["script"]["ssl-cert"]
    except KeyError:
        pass
    return port, result

def remap_scanned_address(address, address_data):
    return {
        "address":  address,
        "hostname": address_data["hostname"],
        "ports":    dict(remap_port(port, port_data) for port,port_data in address_data["tcp"].items())
    }

def remap_scan_data(data_in):
    return [remap_scanned_address(address, address_data) for address, address_data in data_in["scan"].items()]

data_out = remap_scan_data(data_in)