Skip to content

Instantly share code, notes, and snippets.

@wonderbeyond
Created April 13, 2022 08:13
Show Gist options
  • Save wonderbeyond/b0c8dd631cd4ccdfb56d30d135bb7602 to your computer and use it in GitHub Desktop.
Save wonderbeyond/b0c8dd631cd4ccdfb56d30d135bb7602 to your computer and use it in GitHub Desktop.
[Python]检查列表(不限类型)是否符合某种模式(使用通配符)
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