迭代Python数据结构

时间:2014-03-19 22:40:19

标签: python

我在解决这个Python数据结构时遇到了问题:

 data = {'nmap': {'command_line': u'ls',
                  'scaninfo': {u'tcp': {'method': u'connect',
                                        'services': u'80,443'}},
                  'scanstats': {'downhosts': u'0',
                                'elapsed': u'1.18',
                                'timestr': u'Wed Mar 19 21:37:54 2014',
                                'totalhosts': u'1',
                                'uphosts': u'1'}},
         'scan': {u'url': {'addresses': {u'ipv6': u'2001:470:0:63::2'},
                                        'hostname': u'abc.net',
                                        'status': {'reason': u'syn-ack',
                                                   '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': {}
         }
         }
 }

基本上我需要迭代'tcp'键值并提取'script'项的内容(如果存在)。

这是我尝试过的:

items = data["scan"]
for item in items['url']['tcp']:
    if t["script"] is not None:
        print t  

但是我似乎无法让它发挥作用。

3 个答案:

答案 0 :(得分:1)

data['scan']['url']['tcp']是一个字典,所以当你只是迭代它时,你会得到而不是值。如果要迭代值,则必须这样做:

for t in data['scan']['url']['tcp'].values():
    if 'script' in t and t['script'] is not None:
        print(t)

如果您还需要密钥,请反复遍历项目:

for k, t in data['scan']['url']['tcp'].items():
    if 'script' in t and t['script'] is not None:
        print(k, t)

您还需要更改测试以首先检查'script' in t,否则访问t['script']会引发关键错误。

答案 1 :(得分:1)

这将在数据结构中的任何位置找到任何带有键'script'的字典项:

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

对于您的数据,我得到:

>>> find_key(data, 'script')
[{'ssl-cert': 'place holder'}]

要查找端口,请稍微修改:

tcp_dicts = find_key(data, 'tcp') # find all values for key 'tcp'
ports = [] # list to hold ports
for d in tcp_dicts: # iterate through values for key 'tcp'
    if all(isinstance(port, int) for port in d): # ensure all are port numbers
        for port in d:
            ports.append((port, 
                          d[port].get('script'))) # extract number and script

现在你得到类似的东西:

[(80, None), (443, {'ssl-cert': 'place holder'})]

答案 2 :(得分:0)

您的意思是if item["script"]吗?

实际上,如果密钥有可能不存在,请使用get提供的dict方法。

所以请尝试

items = data["scan"]
for item in items['url']['tcp']:
    script = item.get('script')
    if script:
        print script