Created
April 13, 2022 08:13
-
-
Save wonderbeyond/b0c8dd631cd4ccdfb56d30d135bb7602 to your computer and use it in GitHub Desktop.
[Python]检查列表(不限类型)是否符合某种模式(使用通配符)
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
def match_list(lst1: List[Any], lst2: List[Any], /) -> bool: | |
""" | |
检查列表是否符合某种模式 | |
https://stackoverflow.com/questions/8847257/algorithm-to-match-2-lists-with-wildcards | |
参数 lst1, lst2 分别为 目标列表 和 模式,顺序无关, | |
列表元素类型不限, 模式中可以用通配符(*)表示任意数量的任意元素。 | |
>>> A = 'A'; B = 'B'; C = 'C'; D = 'D'; E = 'E' | |
>>> match_list([A, B, C], [A, B, C]) | |
True | |
>>> match_list([A, B, C], ['*', A, B, C]) | |
True | |
>>> match_list([A, B, C], [A, B, C, '*']) | |
True | |
>>> match_list([A, B, C], ['*', A, B, C, '*']) | |
True | |
>>> match_list([A, B, C], ['*', B, C]) | |
True | |
>>> match_list([A, B, C], [A, B, '*']) | |
True | |
>>> match_list([A, B, C], [A, '*']) | |
True | |
>>> match_list([A, B, C], ['*', C]) | |
True | |
>>> match_list([A, B, C], [A, '*', C]) | |
True | |
>>> match_list([A, B, C], [A, '*', '*', C]) | |
True | |
>>> match_list([A, B, C, D], [A, '*', D]) | |
True | |
>>> match_list([A], ['*']) | |
True | |
>>> match_list(['*'], [A]) | |
True | |
>>> match_list([A, C], ['*']) | |
True | |
>>> match_list([A, C], ['*', '*']) | |
True | |
>>> match_list([], []) | |
True | |
>>> match_list([], ['*']) | |
True | |
>>> match_list([A, B, C], [A, B]) | |
False | |
>>> match_list([A, B, C], [B, C]) | |
False | |
>>> match_list(['*'], ['*']) | |
Traceback (most recent call last): | |
... | |
ValueError: Wildcards can be used only in single side. | |
>>> match_list([A, '*'], ['*', A]) | |
Traceback (most recent call last): | |
ValueError: Wildcards can be used only in single side. | |
""" | |
STAR = '*' | |
EMPTY: List[Any] = [] | |
if STAR in lst1 and STAR in lst2: | |
raise ValueError('Wildcards can be used only in single side.') | |
if lst1 == EMPTY: | |
return lst2 in [EMPTY, [STAR]] | |
if lst2 == EMPTY or lst2[0] == STAR: | |
return match_list(lst2, lst1) | |
if lst1[0] == STAR: | |
return match_list(lst1, lst2[1:]) or match_list(lst1[1:], lst2) | |
if lst1[0] == lst2[0] != STAR: | |
return match_list(lst1[1:], lst2[1:]) | |
return False |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment