简体   繁体   English

拼合列表的字典?

[英]Flatten dictionaries of list?

Using python 2.6.5, I am trying to flatten the all the lists that are attach to each dictionary key and put them as one list if possible as a one unique set. 使用python 2.6.5,我试图展平附加到每个字典键的所有列表,并在可能的情况下将它们作为一个唯一列表放到一个列表中。 I tried with two different functions and just not sure what I need to do. 我尝试了两种不同的功能,只是不确定我需要做什么。

The problem I'm having is that it's not returning a list of values but list of keys. 我遇到的问题是它不是返回值列表而是键列表。

For example: 例如:

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

new_list = flatten(dict)

results in [alpha,beta,charile,delta] , but I want is [dg1,dg2,dg3,dg4] . 结果为[alpha,beta,charile,delta] ,但我想要的是[dg1,dg2,dg3,dg4]

What I havve tried: 我尝试过的是:

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), [])

Think about the logic in this part of the code: 考虑一下这部分代码中的逻辑:

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

If c is a list without any lists inside, you're just going to append it onto b , instead of extending . 如果c是一个列表,里面没有任何列表,则只需将其appendb ,而不是extending So, if b = [0] and c = [1, 2] , you'll end up with b = [0, [1, 2]] . 因此,如果b = [0]c = [1, 2] ,您将得到b = [0, [1, 2]]

You need to always extend if c is a list. 如果c是列表,则需要始终扩展。 So, you can do this: 因此,您可以这样做:

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)

This will work. 这将起作用。 But think about what happens if you call flatten on an already-flat list, and you should be able to simplify this further. 但是请考虑一下,如果您在已经平坦的列表上调用flatten会发生什么,那么您应该能够进一步简化它。


Meanwhile, if you don't know how to flatten each value in a dict, you can do it with an explicit loop: 同时,如果您不知道如何平整字典中的每个值,则可以使用显式循环来实现:

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)

I've used d.items() there. 我在那里使用过d.items() In Python 2.x, that gives you a new list, with all the key-value pairs for the dictionary. 在Python 2.x中,这为您提供了一个新列表,其中包含字典的所有键值对。 If the dictionary is huge, making that list just to loop over it can be wasteful, so you may want to use d.iteritems() instead, which gives you a lazy iterator instead of a list. 如果字典很大,那么仅使该列表在其上循环将是浪费的,因此您可能想使用d.iteritems() ,它为您提供了一个懒惰的迭代器而不是列表。


If you know what comprehensions are, you should recognize this pattern of "create an empty collection, loop, add to the collection" as a paradigm case for converting to a comprehension: 如果您知道什么是理解,则应将这种“创建一个空集合,循环,添加到该集合”模式作为转换为理解的范例:

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

Unfortunately, dictionary comprehensions weren't added until 2.7. 不幸的是,字典理解直到2.7才被添加。 But you can get the same effect with the dict function and a generator expression: 但是,您可以通过dict函数和生成器表达式获得相同的效果:

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

Not quite as readable, but it has the same effect, and it works back to 2.4. 可读性不高,但是效果相同,并且可以回溯到2.4。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM