搜索

首页  >  问答  >  正文

python - 遍历list,转换成dict

我有一个list如下

[[['server', ''],['port','8800'],['location','/'],['location','/aa'],['location','bb']],[['server', ''],['port','80'],['location','/'],['location','/aa'],['location','bb']]]

想要得到如下的dict


[{'server': '','port': '8800','location': '/,/aa,/bb'},{'server': '','port': '80','location': '/,/aa,/bb'}]

或者

[{'server': '','port': '8800','location': '/'},{'server': '','port': '8800','location': '/aa'},{'server': '','port': '8800','location': '/bb'},{'server': '','port': '80','location': '/'},{'server': '','port': '80','location': '/aa'},{'server': '','port': '80','location': '/bb'}]

求解

之前有sf上的同学给出了一个例子

def turn2dic(lst):
    global key, value
    dic = {}
    if all([not isinstance(item, list) for item in lst]):
        if len(lst) == 2:
          key, value = lst
        elif len(lst) == 1:
          key=lst[0]
          value=''
        elif len(lst) == 3:
          key=lst[0]
          value=lst[1]
        dic[key] = value
    else:
        for item in lst:
            subdic = turn2dic(item)
            print subdic
            dic.update(subdic)
            print dic
    return dic

但是这个上面代码里,location是覆盖的,因为dic.update(subdic),有什么办法是append的?

PHP中文网PHP中文网2814 天前446

全部回复(4)我来回复

  • 巴扎黑

    巴扎黑2017-04-17 17:56:02

    def single_turn2dic(lst):
        global key, value
        dic = {}
        if all([not isinstance(item, list) for item in lst]):
            if len(lst) == 2:
                key, value = lst
            elif len(lst) == 1:
                key = lst[0]
                value = ''
            elif len(lst) == 3:
                key = lst[0]
                value = lst[1]
                # dic[key] = value
            if value and dic.get(key, ''):
                dic[key] += ',' + value
            else:
                dic[key] = value
    
        else:
            for item in lst:
                subdic = single_turn2dic(item)
                # print subdic
                # dic.update(subdic)
                for name, name_value in subdic.iteritems():
                    if name_value and dic.get(name, ''):
                        dic[name] += ',' + name_value
                    else:
                        dic[name] = name_value
                        # print dic
        return dic
    
    
    servers = [[['server', ''], ['port', '8800'], ['location', '/'], ['location', '/aa'], ['location', 'bb']],
               [['server', ''], ['port', '80'], ['location', '/'], ['location', '/aa'], ['location', 'bb']]]
    
    
    def beautify(servers):
        # lst = []
        if not isinstance(servers[0][0], list):
    
            return single_turn2dic(servers)
        else:
            return [beautify(server) for server in servers]
            
    
    
    
    print beautify(servers)
    

    大致思路就是 [['server', ''], ['port', '8800'], ['location', '/'], ['location', '/aa'], ['location', 'bb']] 这种的视为一个单元处理(函数修改自你给的代码),递归到可以处理程度(因为层数可能不为2)

    回复
    0
  • PHP中文网

    PHP中文网2017-04-17 17:56:02

    代码:

    def turn2dic(lst):
        dic = {}
        if all([not isinstance(item, list) for item in lst]):
            key, value = lst
            dic[key] = value
        else:
            for item in lst:
                subdic = turn2dic(item)
                for key, value in subdic.items():
                    dic.setdefault(key, []).append(value)
        return dic
    
    results = [turn2dic(item) for item in lst]
    
    print results

    结果:

    [{'location': ['/', '/aa', 'bb'], 'port': ['8800'], 'server': ['']}, {'location': ['/', '/aa', 'bb'], 'port': ['80'], 'server': ['']}]
    1. 我觉得不必要的代码可以拿掉,这次的问题既然比较单纯(既然这次都确定底层是双元素的list),那就不用做太多判断和处理(甚至这个recursive 的解法也可以改成简单的做法)。

    2. 我不确定你的资料里面,除了location 以外还有没有别的会重复的东西,我觉得统一处理比较好,所以我字典的值跟你给出的范例不太一样,用list 而不是string 。

    回复
    0
  • 伊谢尔伦

    伊谢尔伦2017-04-17 17:56:02

    分拆开来好看些

    from collections import defaultdict
    
    def testtype(t):
        return lambda x: isinstance(x, t)
    
    def test(t, lst):
        return all(map(t if callable(t) else testtype(t), lst))
    
    def parse_dict(lst):
        dct = defaultdict(lambda: [])
        for k, v in lst:
            dct[k].append(parse(v))
        ret = {}
        for k, v in dct.items():
            if test(str, v):
                v = ','.join(v)
            elif len(v) == 1:
                v = v[0]
            ret[k] = v
            
        return ret
    
    def parse(obj):
        if not isinstance(obj, list):
            return obj
        if test(lambda x: len(x) == 2, obj):
            return parse_dict(obj)
        return list(map(parse, obj))
    
    src= [[['server', ''],['port','8800'],['location','/'],['location','/aa'],['location','bb']],[['server', ''],['port','80'],['location','/'],['location','/aa'],['location','bb']]]
    print(parse(src))

    回复
    0
  • ringa_lee

    ringa_lee2017-04-17 17:56:02

    别人已经授你渔了,一味的要鱼水平不会有提高的

    回复
    0
  • 取消回复