Вопрос

I am working with the output of a parser that outputs a tree in the form of nested lists. Here is an example of the data:

[[['events'], [['worker_connections', '1024']]],
 [['http'],
  [['include', 'mime.types'],
   ['default_type', 'application/octet-stream'],
   ['sendfile', 'on'],
   ['keepalive_timeout', '65'],
   [['server'],
    [['listen', '8080'],
     ['server_name', 'localhost'],
     [['location', '/ '],
      [['root', 'html'], ['index', 'index.html index.htm']]],
     ['error_page', '500 502 503 504 /50x.html'],
     [['location', '= /50x.html '], [['root', 'html']]]]]]]]

Every way of converting it to key-value leads to a list hashability error. Any ideas?

Это было полезно?

Решение

I have the feeling that data is unambiguous. It's logically a dict of strings pointing either at another dict of this kind, or at a string. If the key if pointing at a dict, it is denoted as a one-element list, otherwise as a string.

This is partly guessing, of course, but if I am right, then you can convert it like this:

def convert(a):
  result = {}
  for e in a:
    if isinstance(e[0], list):  # pointing at dict
      result[e[0][0]] = convert(e[1])
    else:
      result[e[0]] = e[1]
  return result

And the result will be

{'events': {'worker_connections': '1024'},
 'http': {'default_type': 'application/octet-stream',
          'include': 'mime.types',
          'keepalive_timeout': '65',
          'sendfile': 'on',
          'server': {'error_page': '500 502 503 504 /50x.html',
                     'listen': '8080',
                     'location': {'root': 'html'},
                     'server_name': 'localhost'}}}

EDIT:

I just saw that this drops some information (when the key is a list but not a one-element list like at ['location', '/ ']). So we can use tuples as keys (they are hashable) and end up at this:

def convert(a):
  result = {}
  for e in a:
    if isinstance(e[0], list):  # pointing at dict
      result[tuple(e[0])] = convert(e[1])
    else:
      result[e[0]] = e[1]
  return result

Producing:

{('events',): {'worker_connections': '1024'},
 ('http',): {'default_type': 'application/octet-stream',
             'include': 'mime.types',
             'keepalive_timeout': '65',
             'sendfile': 'on',
             ('server',): {'error_page': '500 502 503 504 /50x.html',
                           'listen': '8080',
                           'server_name': 'localhost',
                           ('location', '/ '): {'index': 'index.html index.htm',
                                                'root': 'html'},
                           ('location', '= /50x.html '): {'root': 'html'}}}}
Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top