遍历list,转换成dict

cnmoker
  • 71

我有一个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的?

回复
阅读 7.9k
4 个回答
aristotll
  • 5.9k
✓ 已被采纳
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)

dokelung
  • 4.9k

代碼:

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。

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

hsfzxjy
  • 22k

分拆开来好看些

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))
撰写回答
你尚未登录,登录后可以
  • 和开发者交流问题的细节
  • 关注并接收问题和回答的更新提醒
  • 参与内容的编辑和改进,让解决方法与时俱进
宣传栏