将两个嵌套列表高效压缩为单层字典的最佳方法是什么

6 投票
4 回答
607 浏览
提问于 2025-04-17 13:00

比如说:

list1=['k1','k2','k3',['k4','k5',['k6','k7']]]
list2=['v1','v2','v3',['v4','v5',['v6','v7']]]

我想把它们合并成一个字典,像这样:

dict1={'k1':'v1','k2':'v2','k3':'v3','k4':'v4','k5':'v5','k6':'v6','k7':'v7'}

我有一种方法可以做到这一点,但我觉得这样做太耗时间了:

def mergeToDict(keyList, valueList):
    resultDict = {}
    for key, value in itertools.izip(keyList, valueList):
        if type(key) == list and type(value) == list:
            resultDict=dict(resultDict,**mergeToDict(key, value))
        elif type(key) != list and type(key) != dict and type(key) != tuple:
            resultDict[key] = value
    return resultDict

有没有更好的办法呢?

4 个回答

1
>>> def flatten(l):
...     r = []
...     for x in l:
...             if isinstance(x, list):
...                     r.extend(flatten(x))
...             else:
...                     r.append(x)
...     return r

这里提到的 flatten 是一个函数,用来把嵌套的列表变成一个平坦的列表,也就是把里面的内容都拿出来,放在一个一维的列表里。

接下来,dict(zip(flatten(list1), flatten(list2))) 这个写法看起来和你提到的那种方法差不多快。而且,正如大家所说的,这种方法用起来方便很多。

5

我会使用某种扁平化的函数:

def flatten(it):
    if isinstance(it, str):
        yield it
        return
    try:
        for x in it:
            for y in flatten(x):
                yield y
    except TypeError:
        yield it

现在你可以这样做:

from itertools import izip
my_dict = dict(izip(flatten(list1), flatten(list2)))

我觉得这种方法对读者来说更通用,也更容易理解。

1

我觉得如果你的情况只是像你提到的那样(嵌套列表但形状相同),其实根本不需要把它们扁平化。这里有一种方法,在我的电脑上运行速度比你提到的快2到3倍(当然,这种方法只适用于这种情况):

def appendDict(list1, list2, resultDict):
    for idx, val in enumerate(list1):
        if isinstance(val, list):       
            appendDict(val, list2[idx], resultDict)
        else:
            resultDict[val] = list2[idx]

list1=['k1','k2','k3',['k4','k5',['k6','k7']]]
list2=['v1','v2','v3',['v4','v5',['v6','v7']]]
resultDict = {}
appendDict(list1, list2, resultDict)
print resultDict

{'k3': 'v3', 'k2': 'v2', 'k1': 'v1', 'k7': 'v7', 'k6': 'v6', 'k5': 'v5', 'k4': 'v4'}

接下来是不同方法的比较:

你提到的方法,运行10000次的时间是:0.290050983429

其他提议的方法,运行10000次的时间是:0.580717086792

我这个方法,运行10000次的时间是:0.155267000198

虽然这个方法可能没有其他解决方案那么优雅,但看起来性能才是这里最重要的考虑因素。

撰写回答