检查该列表是否包含另一个列表中存在的所有类型的元素

时间:2018-02-20 10:38:15

标签: python python-3.x list types

我有两个Python列表:组件签名。我想检查签名中列出的所有类型是否与组件列表中的至少一个元素匹配。

此处,签名匹配组件列表,因为组件中有字符串和浮点数:

signature = [float, str]
components = [1.0, [], 'hello', 1]

此处,签名 组件不匹配,因为没有列表类型。

signature = [float, list]
components = ['apple', 1.0]

如何在Python 3中表达这个条件?

2 个答案:

答案 0 :(得分:7)

您可以将all()any()与嵌套的生成器表达式结合使用来实现此目的。在这里,我使用isinstance()检查type列表中的每个signature是否与components列表中的对象匹配。使用此功能,您的自定义功能将如下:

def check_match(signature, components):
    return all(any(isinstance(c, s) for c in components) for s in signature)

示例运行:

# Example 1: Condition is matched - returns `True`
>>> signature = [str, int]
>>> components = [1, 'hello', []]
>>> check_match(signature, components)
True

# Example 2: Condition is not matched - returns `False`
>>> signature = [float, list]
>>> components = ['apple', 1.0]
>>> check_match(signature, components)
False

说明:上面嵌套的生成器表达式由两部分组成。第一部分是:

all(...`any()` call... for s in signature)

在这里,我正在迭代signature列表以获取其中的每个元素s。仅当所有 all() 逻辑将返回True时,...any() call...才会返回True。否则它将返回False

其次是 ...any() call... 生成器表达式:

any(isinstance(c, s) for c in components)

此处,对于c列表中的每个元素components,我正在检查外部生成器理解中c的类型是否为s。如果任何类型匹配,any(..)将返回True。如果c都不符合条件,any(...)将返回False

答案 1 :(得分:1)

另一种方法是计算组件中使用的类型集与签名中的类型之间的差异。

unique_signatures = set(signature)
components_type = set(map(type, components))

types_not_used = unique_signatures.difference(components_type)

if len(types_not_used)==0:
    print('All types used')
else:
    print('Types not used:', types_not_used)

我相信这个解决方案有两个主要优点:

  1. 如果您的组件列表很长且有许多重复类型,那么效率会更高,因为您减少了比较次数
  2. 您希望在匹配班级方面有多精确?子类应该通过测试吗?例如,isinstance(1, object)True:这种行为是否适合您?
  3. 使用@Moinuddin(非常好)答案提供的功能,您有以下内容:

    check_match([object], [1, 2.0, 'hello'])
    Out[20]: True
    

    虽然我的回答会检查object与[' int',' float',' str']找不到匹配。