我有一个大字典对象,它有几个键值对(大约16个),但我只对其中3个感兴趣。将这样的字典子集化的最佳方法(最短/有效/最优雅)是什么?

我知道的最好的是:

bigdict = {'a':1,'b':2,....,'z':26} 
subdict = {'l':bigdict['l'], 'm':bigdict['m'], 'n':bigdict['n']}

我相信有比这更优雅的方式。


当前回答

py3.8+中另一种避免big_dict中缺少键的None值的方法使用walrus:

small_dict = {key: val for key in ('l', 'm', 'n') if (val := big_dict.get(key))}

其他回答

至少要短一点:

wanted_keys = ['l', 'm', 'n'] # The keys you want
dict((k, bigdict[k]) for k in wanted_keys if k in bigdict)

此答案使用与所选答案类似的字典推导,但不会对缺失项进行省略。

Python 2版本:

{k:v for k, v in bigDict.iteritems() if k in ('l', 'm', 'n')}

Python 3版本:

{k:v for k, v in bigDict.items() if k in ('l', 'm', 'n')}

使用地图(halfdanrump的答案)对我来说是最好的,尽管还没有计时……

但是如果你使用一个字典,如果你有一个big_dict:

一定要确保你遍历了要求。这是至关重要的,并且会影响算法的运行时间(大O, theta,你能想到的) 把它写得足够通用,以避免在没有键的情况下出现错误。

例如:

big_dict = {'a':1,'b':2,'c':3,................................................}
req = ['a','c','w']

{k:big_dict.get(k,None) for k in req )
# or 
{k:big_dict[k] for k in req if k in big_dict)

请注意,在相反的情况下,req很大,但my_dict很小,您应该通过my_dict进行循环。

一般来说,我们在做一个交集问题的复杂度是O(min(len(dict)) min(len(req)))Python自己的intersection实现考虑了两个集合的大小,所以它看起来是最优的。而且,作为c语言的核心库的一部分,可能比大多数未优化的python语句要快。 因此,我考虑的解决方案是:

dict = {'a':1,'b':2,'c':3,................................................}
req = ['a','c','w',...................]

{k:dic[k] for k in set(req).intersection(dict.keys())}

它将关键操作移到python的c代码中,并适用于所有情况。

你也可以使用map(这是一个非常有用的函数):

sd = dict(map(lambda k:(k, l.get(k, None)), l)))

例子:

large_dictionary = {'a1':123, 'a2':45, 'a3':344}
list_of_keys = ['a1', 'a3']
small_dictionary = dict(map(lambda key: (key, large_dictionary.get(key, None)), list_of_keys))

PS:我借用了.get(键,None)从以前的答案:)

interesting_keys = ('l', 'm', 'n')
subdict = {x: bigdict[x] for x in interesting_keys if x in bigdict}