如何从部分已知键的python字典中检索数据?

13 投票
5 回答
8296 浏览
提问于 2025-04-16 23:31

我有一个 dict,里面的键是字符串类型,但我不知道这些键的具体值,因为它们是在别的地方动态生成的。不过,我知道我想要的那个键包含一个特定的子字符串,并且这个子字符串的键肯定在这个字典里。

那么,获取这个键对应的值的最好、最“符合Python风格”的方法是什么呢?

我想到了两种方法,但这两种方法都让我有点不爽:

for k,v in some_dict.items():
    if 'substring' in k:
        value = v
        break

-- 或者 --

value = [v for (k,v) in some_dict.items() if 'substring' in k][0]

第一种方法比较繁琐,看起来有点丑;而第二种方法虽然更简洁,但在列表推导式中多了一个索引步骤([0]),让我觉得不太舒服。有没有更好的方式来表达第二种,或者更简洁的写法来实现第一种呢?

5 个回答

1
class MyDict(dict):
    def __init__(self, *kwargs):
        dict.__init__(self, *kwargs)

    def __getitem__(self,x):
        return next(v for (k,v) in self.iteritems() if x in k)



# Defining several dicos ----------------------------------------------------    
some_dict = {'abc4589':4578,'abc7812':798,'kjuy45763':1002}

another_dict = {'boumboum14':'WSZE x478',
                'tagada4783':'ocean11',
                'maracuna102455':None}

still_another = {12:'jfg',45:'klsjgf'}



# Selecting the dicos whose __getitem__ method will be changed -------------       
name,obj = None,None
selected_dicos = [ (name,obj) for (name,obj) in globals().iteritems()
                   if type(obj)==dict
                   and all(type(x)==str for x in obj.iterkeys())]

print 'names of selected_dicos ==',[ name for (name,obj) in selected_dicos] 



# Transforming the selected dicos in instances of class MyDict -----------
for k,v in selected_dicos:
    globals()[k] = MyDict(v)



# Exemple of getting a value ---------------------------------------------      
print "some_dict['7812'] ==",some_dict['7812']

结果

names of selected_dicos == ['another_dict', 'some_dict']
some_dict['7812'] == 798
1

这样做怎么样:

value = (v for (k,v) in some_dict.iteritems() if 'substring' in k).next()

它会在找到第一个匹配项时立即停止。

不过,它的复杂度还是O(n),这里的n指的是键值对的数量。如果想加快搜索速度,你需要使用像后缀列表或后缀树这样的结构。

10

可以选择用第二种写法来保持第一种的性能特点。

使用生成器表达式,而不是列表推导式:

value = next(v for (k,v) in some_dict.iteritems() if 'substring' in k)

括号里的表达式会返回一个迭代器,你可以请求它提供下一个,也就是第一个元素。之后不会再处理其他元素。

撰写回答