来自 ordereddict 的子字段?

Subset fields from an ordereddict?

所以,我有一个有序的字典,它有一堆 key/value 对。我可以使用 items() 方法提取所有它们。但是,如果我只想 select 其中的一部分呢?

>>> import collections
>>> d = collections.OrderedDict({'banana': 3, 'apple': 4, 'pear': 1,'orange': 2})
>>> d.items()
[('apple', 4), ('banana', 3), ('orange', 2), ('pear', 1)]

如果我只想要苹果和香蕉怎么办?

有什么方法可以指定我想要的键吗?

>>> d['apple','banana'] <-- does not work

我考虑在最后使用列表理解来过滤结果,但看起来很乱,我希望有更好的方法。

我不知道是否存在任何方法,但如果您发现自己必须在整个代码库中执行此操作,那么创建一个通用方法可能是值得的。也许像

>>> specific_dict_items = lambda d, l: [(key, d.get(key, '')) for key in l]
>>> specific_dict_items({1:1, 2:2, 3:3, 4:4, 5:5}, [1, 3, 5, 7])
[(1, 1), (3, 3), (5, 5), (7, '')]

您可以定义一个单行代码来完成它:

>>> import collections
>>> d = collections.OrderedDict({'banana': 3, 'apple': 4, 'pear': 1,'orange': 2})
>>> d.items()
[('orange', 2), ('pear', 1), ('banana', 3), ('apple', 4)]
>>>
>>> subset = lambda d, *keys: [(key, d[key]) for key in keys]
>>> subset(d, 'apple', 'banana')
[('apple', 4), ('banana', 3)]

作为奖励,它也适用于常规 dict 对象。

更新

要获得与 OrderedDict 相同顺序的结果列表,正如@Maxim Veksler 似乎认为您可能想要的那样,必须以赋予其特定顺序的方式定义有序字典。在 3.6 之前的 Python 版本中,必须做这样的事情而不是你的问题:

d = collections.OrderedDict([('banana', 3), ('apple', 4), ('pear', 1), ('orange', 2)])

它向构造函数传递一个 list 参数,而不是一个常规的 dict

所以假设已经完成(或者如果您使用的是 Python 3.6+,则没有),您可以像这样定义 subset() 函数:

subset = lambda d, *keys: [(key, d[key]) for key in d.keys() if key in set(keys)]

如果正确创建样本 OrderedDict 输入:

,那么 return 这个结果
>>> subset(d, 'apple', 'banana')
[('banana', 3), ('apple', 4)]

请注意,列表 returned 中的对现在的顺序与键在 OrderedDict 中的顺序相同。

您很可能最终会以某种方式使用列表推导式。这是一种将列表理解隐藏在方法实现中的方法:

from collections import OrderedDict

class MultOrderedDict(OrderedDict):
    def items(self, *items):
        all = super(MultOrderedDict, self).items()
        if not items:
            return all
        return type(self)((key, value) for (key, value) in all if key in items).items()

使用 class 定义(假设它在 multorddict.py 中)你可以这样做:

>>> from multorddict import MultOrderedDict
>>> mod = MultOrderedDict(banana=3, apple=4, pear=1, orange=2)
>>> mod.items()
[('orange', 2), ('pear', 1), ('apple', 4), ('banana', 3)]
>>> mod.items('apple','banana')
[('apple', 4), ('banana', 3)]
>>> 

这种方法改变了 items 方法的语义,这可能不是什么好事。