有序的子集中的子集字段?

时间:2016-10-31 01:45:02

标签: python ordereddictionary

所以,我有一个有序的字典,它有一堆键/值对。我可以使用items()方法提取所有它们。但是,如果我只想选择其中的一些呢?

>>> 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

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

3 个答案:

答案 0 :(得分:3)

您可以定义一个单行来执行此操作:

>>> 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输入,那么会返回此结果:

>>> subset(d, 'apple', 'banana')
[('banana', 3), ('apple', 4)]

请注意,返回列表中的对现在与OrderedDict中的密钥的顺序相同。

答案 1 :(得分:1)

我不知道存在哪种方法,但如果您发现自己必须完成代码库,那么创建通用方法可能是值得的。也许像是

>>> 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, '')]

答案 2 :(得分:0)

你最有可能以这种或那种方式使用列表理解。这是一种将列表理解隐藏在方法实现中的方法:

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()

使用该类定义(假设它在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方法的语义,这可能不是一件好事。