You can implement wild-card matching by using a special object that always compares as equal to any other object. Eg
#!/usr/bin/env python
class Any:
def __eq__(self, other):
return True
def __repr__(self):
return 'Any'
ANY = Any()
#Test
if 1:
print ANY
for v in [1,2,'a', 'b', (2,3,4), None]:
print v, v == ANY
print
def match(target, data):
''' Check that sequence data matches sequence target '''
return len(data) == len(target) and all(u==v for u, v in zip(target, data))
data_list = [(0, 1), (1, 2), (5, 5), (4, 1)]
target = (ANY, 1)
print [v for v in data_list if match(target, v)]
output
Any
1 True
2 True
a True
b True
(2, 3, 4) True
None True
[(0, 1), (4, 1)]
Here's a better version with a fancier Any
class, thanks to Antti Haapala. It prints the same output as the code above.
#!/usr/bin/env python
class AnyBase(type):
def __eq__(self, other):
return True
def __repr__(self):
return 'Any'
@classmethod
def __subclasscheck__(cls, other):
return True
@classmethod
def __instancecheck__(cls, other):
return True
class Any(object):
__metaclass__ = AnyBase
def __init__(self):
raise NotImplementedError("How'd you instantiate Any?")
#Test
if 1:
print Any
for v in [1,2,'a', 'b', (2,3,4), None]:
print v, v == Any
print
def match(target, data):
''' Check that sequence data matches sequence target '''
return len(data) == len(target) and all(u==v for u, v in zip(target, data))
data_list = [(0, 1), (1, 2), (5, 5), (4, 1)]
target = (Any, 1)
print [v for v in data_list if match(target, v)]
To use the first version we really should create an instance of the class, but the Any
class in the second version is designed to be used directly. Also, the second version shows how to handle isinstance
& subclass
checks; depending on context you may wish to restrict those tests.