字典键中的通配符

7
假设我有一个字典:
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)

1
“*”只是一个字符,除非被命令或函数用作通配符,例如glob.glob()fnmatch.fnmatch()。但是,在字符串上使用“==”仅仅是调用str.__eq__()方法,并不是通配符。如果您想要使用re.match/find...(),则需要将通配符设置为“V.*”。 - smci
有很多重复的问题,比如Python中的Unix文件名通配符? - smci
1
@smci,在字典的上下文中,我认为我的解决方案是有效的,不可能被放在dup上,我认为它应该保持开放状态,因为(潜在地)可能会有人想出更好的想法。 - jpp
2个回答

6

你可以使用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)的时间复杂度。对于大型字典,这可能成为一个问题。仅建议在查找性能不是问题的情况下使用。


哇,我喜欢那个!超级简单!运行得很好;谢谢。 - gwydion93
1
@jpp,感谢您的评论。我将您的评论作为注释添加到答案中。 - falsetru

4

我建议将你的单一字典分成两个,一个是常规字典,另一个则是通过通配符推导而来的字典,这样可以保持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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接