Python-迭代列表和字典
嗨,我在转载这个问题,但提供更多关于我试图实现的信息。在过去的几天里,它让我发疯,而我似乎无法取得进展。基本上,我有这样的数据结构:Python-迭代列表和字典,python,list,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',
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'}}]}]
根据@jornsharpe之前的建议,我创建了一个帮助函数,使我能够找到键。事实证明,这很有帮助,但我仍在努力获得预期的结果
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
这里的任何帮助都将不胜感激 这并不难;您只需仔细查看导致所需内容的数据结构—由于格式不当,这变得更加困难,因此我重新缩进了您的输入并标记了键(
很明显,你在上一个问题中接受的答案并没有那么有帮助。那么,你为什么不回去看看其他答案,这些答案更侧重于导航你的实际结构(而不是在任何地方随机查找键)试着自己想点什么?我认为你的数据输出格式不好。你用逗号代替冒号。应该是: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'placeholder','state':u'open','reason':u'syn-ack'}]}]
是的-很抱歉修复了它。谢谢!非常感谢-我花了这么长时间盯着它看,看不到树,撞到了一堵墙。正如你所说的,由于格式不好而变得更加困难。我将详细研究你的示例。再次感谢。
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)
[{'address': u'2a00:2384:0:208f::13',
'hostname': u'static.abc.com',
'ports': {80: {'reason': u'syn-ack', 'state': u'open'},
443: {'reason': u'syn-ack',
'ssl_cert': u'place holder',
'state': u'open'}}},
{'address': u'2a00:2384:0:208f::15',
'hostname': u'static.xyz.com',
'ports': {80: {'reason': u'syn-ack', 'state': u'open'},
443: {'reason': u'syn-ack',
'ssl_cert': u'place holder',
'state': u'open'}}},
{'address': u'2a00:2384:0:208f::16',
'hostname': u'static.edf.com',
'ports': {80: {'reason': u'syn-ack', 'state': u'open'},
443: {'reason': u'syn-ack',
'ssl_cert': u'place holder',
'state': u'open'}}}]