字典键中的通配符

Wildcard in dictionary key

提问人:gwydion93 提问时间:10/5/2018 最后编辑:smcigwydion93 更新时间:10/5/2018 访问量:6073

问:

假设我有一本字典:

rank_dict = {'V*': 1, 'A*': 2, 'V': 3,'A': 4}

正如你所看到的,我在一个 V 的末尾添加了一个 *,虽然 3 可能只是 V 的值,但我想要另一个 V1、V2、V2234432 等键......我想检查一下:

checker = 'V30'

并获取值。正确的语法是什么?

for k, v in rank_dict.items():
    if checker == k:
        print(v)
python-3.x 字典 通配符 glob

评论

1赞 smci 10/5/2018
“*”只是一个字符。它不是通配符,除非它被将其视为通配符的命令或函数使用,例如 或 。但是字符串上的“==”只是方法,它不是。如果你想使用,你需要通配符glob.glob()fnmatch.fnmatch()str.__eq__()re.match/find...()V.*
0赞 smci 10/5/2018
有很多重复项,比如 Python 中的 Unix 文件名通配符?
1赞 jpp 10/5/2018
@smci,在字典的上下文中,我认为我的解决方案是有效的,不可能放在 dup 上,我认为它应该保持开放,因为(可能)有人可能会想出更好的主意。

答:

6赞 falsetru 10/5/2018 #1

您可以使用 fnmatch.fnmatch 来匹配 Unix shell 样式的通配符:

>>> import fnmatch
>>> fnmatch.fnmatch('V34', 'V*')
True

>>> rank_dict = {'V*': 1, 'A*': 2, 'V': 3,'A': 4}
>>> checker = 'V30'
>>> for k, v in rank_dict.items():
...     if fnmatch.fnmatch(checker, k):
...         print(v)
... 
1

注意:每次查找都会有 O(n) 个时间复杂度。这可能会成为大型词典的问题。仅当查找性能不是问题时才建议使用。

评论

0赞 gwydion93 10/5/2018
哇,我喜欢!超级简单!像魅力一样工作;谢谢。
1赞 falsetru 10/5/2018
@jpp,谢谢你的评论。我添加了您的评论以回答为注意。
4赞 jpp 10/5/2018 #2

我会将你的单个字典一分为二,一个是常规字典,一个是通配符派生的字典,这样你就可以保持 O(1) 查找时间的复杂度。

rank_dict = {'V*': 1, 'A*': 2, 'V': 3,'A': 4}

d1 = {k: v for k, v in rank_dict.items() if not k.endswith('*')}
d2 = {k[0]: v for k, v in rank_dict.items() if k.endswith('*')}

def get_val(key, d1, d2):
    return d1.get(key, d2.get(key[0]))

get_val('V', d1, d2)    # 3
get_val('V30', d1, d2)  # 1