I have two Python lists: components and signature. I want to check whether all the types listed in signature match at least one of the elements in the component list.
Here, the signature matches the component list, because there is both a string and a float in components:
signature = [float, str]
components = [1.0, [], 'hello', 1]
Here, signature does not match components, because there is no list type.
signature = [float, list]
components = ['apple', 1.0]
How can I express this condition in Python 3?
You may use combination of all()
and any()
with nested generator expression to achieve this. Here I am using isinstance()
to check for each type
in your signature
list matches with the object in components
list. Using this, your custom function will be as:
def check_match(signature, components):
return all(any(isinstance(c, s) for c in components) for s in signature)
Sample Run:
# 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
Explanation: Above nested generator expression is comprised of two parts. First part is:
all(...`any()` call... for s in signature)
Here, I am iterating signature
list to get each element s
present in it. all()
will return True
only when all the ...any() call...
logic will return True
. Else it will return False
.
Second is the ...any() call...
generator expression as:
any(isinstance(c, s) for c in components)
Here, for each element c
in components
list, I am checking whether the type of c
is s
from the external generator comprehension. If any of the type matches, any(..)
will return True
. If none of c
matches the condition, any(...)
will return False
.
Another approach is to calculate the difference between the set of types used in components and those you have in signature.
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)
I believe there are two main advantages with this solution:
isinstance(1, object)
is True
: is this behavior desirable to you? Using the function provided by the (very good) answer of @Moinuddin, you have the following:
check_match([object], [1, 2.0, 'hello'])
Out[20]: True
while my answer would check object
versus ['int', 'float', 'str'] finding no match.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With