列出列表的词典?

时间:2014-11-12 01:16:33

标签: python list dictionary

使用python 2.6.5,我试图压缩附加到每个字典键的所有列表,并将它们作为一个列表放在一起作为一个唯一集合。我尝试了两种不同的功能,但不确定我需要做什么。

我遇到的问题是它没有返回值列表而是返回键列表。

例如:

dict = {'alpha': [[], ['dg1']],
        'beta': [[], ['dg2'], ['dg3'], ['dg4'], ['dg1']],
        'charlie': [[], ['dg1']],
        'delta': [[], ['dg4']]}

new_list = flatten(dict)

结果为[alpha,beta,charile,delta],但我想要的是[dg1,dg2,dg3,dg4]

我曾尝试过:

def flatten(a):
    b = []
    for c in a:
        if isinstance(c, list) and any(isinstance(i, list) for i in c):
            b.extend(flatten(c))
        else:
            b.append(c)
    return b

def flatten_list(lst):
    """
    Utility to flatten a list of list.
    If outer list is not list or None, it returns the original object.
    It will return None for None.
    """
    if not isinstance(lst, list):
        return lst
    return sum(([x] if not isinstance(x, list) else flatten_list(x)
                    for x in lst), [])

1 个答案:

答案 0 :(得分:3)

考虑这段代码中的逻辑:

if isinstance(c, list) and any(isinstance(i, list) for i in c):
    b.extend(flatten(c))
else:
    b.append(c)

如果c是一个没有任何列表的列表,您只需将append转到b,而不是extending。因此,如果b = [0]c = [1, 2],您最终会得到b = [0, [1, 2]]

如果c是列表,则需要始终扩展。所以,你可以这样做:

if isinstance(c, list):
    if any(isinstance(i, list) for i in c):
        b.extend(flatten(c))
    else:
        b.extend(c)
else:
    b.append(c)

这会奏效。但是想想如果你在一个已经很平坦的列表上调用flatten会发生什么,你应该能够进一步简化这一点。


与此同时,如果您不知道如何压缩字典中的每个值,您可以通过显式循环来实现:

d = {'alpha': [[], ['dg1']], 'beta': [[], ['dg2'], ['dg3'], ['dg4'], ['dg1']], 'charlie': [[], ['dg1']], 'delta': [[], ['dg4']]}
new_d = {}
for k, v in d.items():
    new_d[k] = flatten(v)

我在那里使用过d.items()。在Python 2.x中,它为您提供了一个新列表,其中包含字典的所有键值对。如果字典很大,那么使该列表只是为了循环它可能是浪费,所以你可能想要使用d.iteritems(),这会给你一个懒惰的迭代器而不是列表。


如果你知道什么是理解,你应该认识到这种模式"创建一个空集合,循环,添加到集合"作为转换为理解的范例:

new_d = {k: flatten(v) for k, v in d.items()}

不幸的是,直到2.7才增加词典理解。但是你可以使用dict函数和生成器表达式获得相同的效果:

new_d = dict((k, flatten(v)) for k, v in d.items())

不太可读,但效果相同,可以回到2.4。