【问题标题】:How to flatten a list of dicts and single items into a list where single items should be duplicated如何将字典和单个项目的列表展平为应复制单个项目的列表
【发布时间】:2021-01-22 16:51:12
【问题描述】:

我有这个数组:

import numpy as np

array_start = [{'Very Ripe': 5}, {'Ripe': 2}, np.nan]

我想生成一个包含单个项目的数组并复制 np.nan 值,以便最终得到这个数组:

>>> array_end
['Very Ripe', 5, 'Ripe', 2, nan, nan]

到目前为止,我已经尝试了以下方法:

>>> array_end = [item.items() if isinstance(item,dict) else np.repeat(np.nan,2) for item in array_start]
>>> array_end
[dict_items([('Very Ripe', 5)]), dict_items([('Ripe', 2)]), array([nan, nan])]

这让我有所收获,但似乎更难在array_end 中解压缩dict_items 和后一个数组(np.nans)以生成目标array_end

['Very Ripe', 5, 'Ripe', 2, nan, nan]

【问题讨论】:

    标签: python list dictionary flatten


    【解决方案1】:

    您可以遍历array_list 中的每个项目,检查它是否是字典,如果不是则复制该项目,或者如果是则提取所有字典项目。你有几个选择来做到这一点

    带有list.extend的简单循环:

    import numpy as np
    
    array_start = [{'Very Ripe': 5}, {'Ripe': 2}, np.nan]
    
    result = []
    for element in array_start:
        if isinstance(element, dict):
            for item in element.items():
                result.extend(item)
        else:
            result.extend((element, element))
    print(result)
    # ['Very Ripe', 5, 'Ripe', 2, nan, nan]
    

    生成器函数:

    def to_flat_list(array):
        for element in array:
            if isinstance(element, dict):
                for item in element.items():
                    yield from item
            else:
                yield element
                yield element
    
                
    result = list(to_flat_list(array_start))
    print(result)
    # ['Very Ripe', 5, 'Ripe', 2, nan, nan]
    

    列表理解中的嵌套循环:

    result = [item 
              for element in array_start
              for pair in (element.items() if isinstance(element, dict) 
                           else [(element, element)])
              for item in pair]
    print(result)
    # ['Very Ripe', 5, 'Ripe', 2, nan, nan]
    

    itertools.chain.from_iterable:

    from itertools import chain
    
    flatten = chain.from_iterable
    result = list(flatten((flatten(item.items()) 
                           if isinstance(item, dict) 
                           else (item, item) 
                           for item in array_start)))
    print(result)
    # ['Very Ripe', 5, 'Ripe', 2, nan, nan]
    

    可能还有其他一些方法。但这些应该就足够了。

    【讨论】:

      【解决方案2】:

      它必须在单个列表理解中吗?不要让简洁成为功能代码的敌人。

      这是一种使用两个列表推导式的方法:

      array_end = [list(*item.items()) if isinstance(item,dict) else np.repeat(np.nan,2) for item in array_start]
      print(array_end)
      # Output: [['Very Ripe', 5], ['Ripe', 2], array([nan, nan])]
      

      我们在第一个列表推导中将 dict_items() 对象解压缩到列表中。然后,我们有一个列表(或 numpy 数组)列表,我们可以对其运行另一个理解来展平它。

      array_final = [y for x in array_end for y in x]
      print(array_final)
      # Output: ['Very Ripe', 5, 'Ripe', 2, nan, nan]
      

      【讨论】:

        猜你喜欢
        • 2010-11-20
        • 1970-01-01
        • 2019-05-07
        • 2013-12-07
        • 2023-01-07
        • 2023-01-20
        • 1970-01-01
        • 2015-06-18
        相关资源
        最近更新 更多