展平python中嵌套的有序字典的列表

时间:2018-12-07 14:15:48

标签: python list dictionary

我有点困惑如何从Python的有序列表的嵌套列表中提取信息。例如:

list_of_interest = [OrderedDict([('name', 'Viscozyme'), ('company', 'Roche (Chile)')]),
 [OrderedDict([('name', 'Davictrel'), ('company', None)]),
  OrderedDict([('name', 'Enbrel Sureclick'), ('company', None)]),
  OrderedDict([('name', 'Tunex'), ('company', None)])],
 OrderedDict([('name', 'Angiox'), ('company', None)]),
 [OrderedDict([('name', 'Enantone'), ('company', None)]),
  OrderedDict([('name', 'Leuplin'), ('company', 'Takeda')]),
  OrderedDict([('name', 'LeuProMaxx'), ('company', 'Baxter/Teva')]),
  OrderedDict([('name', 'Leupromer'), ('company', None)]),
  OrderedDict([('name', 'Lutrate'), ('company', None)]),
  OrderedDict([('name', 'Memryte'), ('company', 'Curaxis')]),
  OrderedDict([('name', 'Prostap 3'), ('company', 'Takeda UK')]),
  OrderedDict([('name', 'Prostap SR'), ('company', 'Takeda UK')]),
  OrderedDict([('name', 'Viadur'), ('company', 'Bayer AG')])],
 OrderedDict([('name', 'Geref'), ('company', 'Serono Pharma')])]

我需要提取'name'下的所有项目。

所以我需要一个功能:

get_names(list_of_interest) --> ['Viscozyme', 'Davictrel', 'Enbrel Sureclick', 'Tunex', 'Angiox', 'Enantone', ..., 'Geref']

老实说,我尝试过嵌套列表推导,生成器表达式甚至pandas数据框,但是由于某些子列表是单个值,因此失败了。

6 个答案:

答案 0 :(得分:6)

from collections import OrderedDict

list_of_interest =\
    [OrderedDict([('name', 'Viscozyme'), ('company', 'Roche (Chile)')]),
    [OrderedDict([('name', 'Davictrel'), ('company', None)]),
     OrderedDict([('name', 'Enbrel Sureclick'), ('company', None)]),
     OrderedDict([('name', 'Tunex'), ('company', None)])],
     OrderedDict([('name', 'Angiox'), ('company', None)]),
    [OrderedDict([('name', 'Enantone'), ('company', None)]),
     OrderedDict([('name', 'Leuplin'), ('company', 'Takeda')]),
     OrderedDict([('name', 'LeuProMaxx'), ('company', 'Baxter/Teva')]),
     OrderedDict([('name', 'Leupromer'), ('company', None)]),
     OrderedDict([('name', 'Lutrate'), ('company', None)]),
     OrderedDict([('name', 'Memryte'), ('company', 'Curaxis')]),
     OrderedDict([('name', 'Prostap 3'), ('company', 'Takeda UK')]),
     OrderedDict([('name', 'Prostap SR'), ('company', 'Takeda UK')]),
     OrderedDict([('name', 'Viadur'), ('company', 'Bayer AG')])],
     OrderedDict([('name', 'Geref'), ('company', 'Serono Pharma')])]

names = []
for item in list_of_interest:
    if isinstance(item, OrderedDict):
        names.append(item['name'])
    else:
        for list_ord_dict in item:
            names.append(list_ord_dict['name'])

print(names)
#['Viscozyme', 'Davictrel', 'Enbrel Sureclick', 'Tunex', 'Angiox', 'Enantone', 'Leuplin', 'LeuProMaxx', 'Leupromer', 'Lutrate', 'Memryte', 'Prostap 3', 'Prostap SR', 'Viadur', 'Geref']

您有两种类型的项目,您可以知道通过主列表迭代并打印该类型。如果您更深入,则可以使用一个递归函数,该递归函数在遇到列表时会自行调用。对于您提供的数据集,上面的代码可以正常工作。

答案 1 :(得分:3)

尝试这个:

def flat(l):
    ret = list()
    for ll in l:
        if isinstance(ll, (OrderedDict, list)):
            ret.extend(flat(ll))
        else:
            ret.append(ll)
    return ret

它应该与任何深度的列表一起使用

答案 2 :(得分:3)

您可以使用自定义递归函数展平嵌套列表:

def flatten(l):
    for el in l:
        if isinstance(el, list):
            yield from flatten(el)
        else:
            yield el

然后简单地创建一个新的列表理解,以收集每个OrderedDict中的所有名称:

print([d["name"] for d in flatten(list_of_interest)])
# ['Viscozyme', 'Davictrel', 'Enbrel Sureclick', 'Tunex', 'Angiox', 'Enantone', 'Leuplin', 'LeuProMaxx', 'Leupromer', 'Lutrate', 'Memryte', 'Prostap 3', 'Prostap SR', 'Viadur', 'Geref']

注意yield from flatten(el)语法与for x flatten(el): yield x等效。这只是python 3中可用的简洁sytnax。

答案 3 :(得分:2)

您必须遍历列表,然后递归到每个嵌套列表中

def get_names(list_of_interest):
    names = []
    for d in list_of_interest:
        if ininstance(d, list):
            names.extend(get_names(d))
        else:
            names.append(d['name'])
    return names 

答案 4 :(得分:2)

从stackoverflow.com/a/9808122/1281485中采用我的答案,并将其调整为此处稍有不同的任务:

def find(key, value):
  if isinstance(value, dict):
    for k, v in value.iteritems():
      if k == key:
        yield v
      else:
        for result in find(key, v):
          yield result
  elif isinstance(value, list):
    for element in value:
      for result in find(key, element):
        yield result

然后:

print(list(find('name', list_of_interest)))

答案 5 :(得分:2)

另一个递归选项:

def flat(lst, res = None):
  if res == None: res = []
  for item in lst:
    if not type(item) == list: res.append(item['name'])
    else: flat(item, res)
  return res

print(flat(list_of_interest))
#=> ['Viscozyme', 'Davictrel', 'Enbrel Sureclick', 'Tunex', 'Angiox', 'Enantone', 'Leuplin', 'LeuProMaxx', 'Leupromer', 'Lutrate', 'Memryte', 'Prostap 3', 'Prostap SR', 'Viadur', 'Geref']