[英]Flatten dictionaries of list?
使用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), [])
考虑一下这部分代码中的逻辑:
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。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.