动态获取列表 - 词典混合列表中的值

时间:2016-01-20 00:56:38

标签: python list python-2.7 dictionary

我目前正在尝试获取从MongoDB查询收到的JSON文档的某些字段的值。查询返回一个字典,并在查询中使用.values(),我得到一个值列表。但是,此列表的某些值是包含字典的另一个列表。我试图找出动态获取列表中已有值的值列表以及子列表中找到的词典值的最佳方法。

例如,我有一个名为text_list的列表:

>>> text_list 
[[{u'field1': u'field1_value1', u'field2': u'field2_value1'},
  {u'field2': u'field2_value2'}],
 u'value1',
 u'value2']

我想从这个列表中只获取值field1_value1, field2_value1, field2_value2, value1, value2(并将它们放在一个新列表中,或者只是将值连接成一个大字符串)。

我想为多个列表执行此过程,但有时列表会有这些额外的词典,有时则不会。 什么是最好(最少计算密集/最快)的方法来获取我正在寻找的值

我想出了以下方法:

def concatenate_list(inList):
    outString = '' #empty string that the values will be added to
    for item in inList:
        if type(item) == list:
            for i in np.arange(len(item)):
                for subitem in item[i].values():
                    outString = outString+' '+subitem
        else:
            outString = outString+' '+item
    return outString

>>> concatenate_list(text_list)
u'field1_value1 field2_value1 field2_value2 value1 value2'

这给了我正在寻找的结果,但必须有一个比这更好的方法。当我必须在数千个列表中运行此功能时,我不会发现这非常有效。

1 个答案:

答案 0 :(得分:2)

你可以编写一个递归函数,只有当它们既不是列表也不是字典时才可以打印这些值,就像这样

>>> def rec_fetcher(obj):
...     if isinstance(obj, list):
...         for item in obj:
...             yield from rec_fetcher(item)
...     elif isinstance(obj, dict):
...         for item in obj:
...             yield from rec_fetcher(obj[item])
...     else:
...         yield obj
... 
>>> list(rec_fetcher(data))
['field1_value1', 'field2_value1', 'field2_value2', 'value1', 'value2']

注意:字典无序。因此,字典中的值可能与文字传递的位置不同。

yield from是一个Python 3.x的东西。如果您使用的是Python 2.7,则可以简单地迭代递归调用并生成数据,如此

>>> def rec_fetcher(obj):
...     if isinstance(obj, list):
...         for item in obj:
...             for value in rec_fetcher(item):
...                 yield value
...     elif isinstance(obj, dict):
...         for item in obj:
...             for value in rec_fetcher(obj[item]):
...                 yield value
...     else:
...         yield obj
... 
>>> list(rec_fetcher(data))
[u'field2_value1', u'field1_value1', u'field2_value2', u'value1', u'value2']