如何从部分已知键的python字典中检索数据?
我有一个 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)
括号里的表达式会返回一个迭代器,你可以请求它提供下一个,也就是第一个元素。之后不会再处理其他元素。