简体   繁体   English

删除所有元素都不为的嵌套列表

[英]Remove nested lists where all elements are None

I have a series of lists (within a dictionary) and I would like to remove any which only have None as elements. 我有一系列列表(在字典中),我想删除仅以None为元素的任何列表。 However, the lists have various different formattings eg 但是,列表具有各种不同的格式,例如

x=[None,[None],[None]]
x=[None,None,None]
x=[None,[None,None],[None,None]]

where any None could be replaced with a value. 其中任何None都可以替换为值。

Any example would be the following dictionary: 任何示例将是以下字典:

dict={"x1": [None,None,None],"x2": [None,[None],[None]], "x3": [None,[1],[0.5]],
      "x4":[None,[None,None],[None,None]],"x5":[None,[180,-360],[90,-180]]}

In this case I would like to keep (key,value) pairs "x3" and "x5" as they contain values that are not all None , but would like to remove "x1" , "x2" , and "x4" thus returning: 在这种情况下,我想保留(key,value)"x3""x5"因为它们包含的值"x5"None ,但要删除"x1""x2""x4"从而返回:

dict={"x3": [None,[1],[0.5]], "x5":[None,[180,-360],[90,-180]]}

A simple list comprehension on the various lists ( x ) in the dictionary such as 对字典中各种列表( x )的简单列表理解,例如

any(e is not None for e in x)

reads [None] entries as not None and returns True . [None]条目读取not None并返回True

How can I determine which lists actually contain a value rather than [None] elements. 如何确定哪些列表实际包含值而不是[None]元素。 I have looked at options for removing the square brackets, eg using itertools such as suggested here [ Remove brackets from list in Python ], but these all rely on all the elements in the list being formatted in the same way, whereas I have mixed formatting. 我已经研究了删除方括号的选项,例如使用itertools如此处建议的[ 从Python的列表中删除括号 ]所建议的),但是这些都依赖于列表中所有元素的格式化方式相同,而我混合使用格式。 I am unable to change the formatting as it is required in this format elsewhere in the software. 我无法更改格式,因为该格式在软件的其他位置是必需的。

According to the comment of Benjamin, this function should return True if all the nested list in list_input contains the same value val_to_check and False otherwise: 根据Benjamin的评论,如果list_input中的所有嵌套列表list_input包含相同的值val_to_check ,则此函数应返回True,否则返回False:

def check_val(list_input, val_to_check):
    for elem in list_input:
        if isinstance(elem, list):
            if check_val(elem, val_to_check) == False:
                return False
        else:
            if elem != val_to_check:
                return False
    return True

You can write a custom recursive function to check if all the elements of the nested list are None or not. 您可以编写一个自定义递归函数来检查嵌套列表中的所有元素是否为None

def is_none(a):
    return all(x is None if not isinstance(x, list) else is_none(x) for x in a)

my_dict = {"x1": [None, None, None],
           "x2": [None, [None], [None]],
           "x3": [None, [1], [0.5]],
           "x4": [None, [None, None], [None, None]],
           "x5": [None, [180, -360], [90, -180]]}

new_dict = {k: v for k, v in my_dict.items() if not is_none(v)}
print(new_dict)
# {'x3': [None, [1], [0.5]], 'x5': [None, [180, -360], [90, -180]]}

This solution is similar in nature to that of Keyur Potdar, but it works for all kinds of containers, not only list : 该解决方案本质上与Keyur Potdar的解决方案相似,但它适用于各种容器,不仅限于list

my_dict = {
    "x1": [None, None, None],
    "x2": [None, [None], [None]],
    "x3": [None, [1], [0.5]],
    "x4": [None, [None, None], [None, None]],
    "x5": [None, [180, -360], [90, -180]],
}

def all_None(val):
    # Check for None
    if val is None:
        return True
    # val is not None
    try:
        # val may be a container
        return all(all_None(el) for el in val)
    except:
        # val is neither None nor a container
        return False

my_dict_filtered = {key: val for key, val in my_dict.items() if not all_None(val)}
print(my_dict_filtered)

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

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