通过嵌套字典键获取唯一列表项

时间:2015-10-09 16:19:06

标签: python dictionary nested

我将列表作为嵌套在另一个名为data的字典中的字典值。我一直在尝试快速找到特定嵌套密钥中的所有唯一列表项,例如key1key2

我想出了以下功能,这看起来效率不高。我有什么想法可以加快速度,并且更加有点pythonic?

Python功能

def get_uniq_by_value(data, val_name):
    results = []
    for key, value in data.iteritems():
        for item in value[val_name]:
            if item not in results:
                results.append(item)
    return results

示例数据

data = {
"top1": {
    "key1": [
        "there is no spoon", "but dictionaries are hard",
    ],
    "key2": [
        "mad max fury road was so good",
    ]
},
"top2": {
    "key1": [
        "my item", "foo bar"
    ],
    "key2": [
        "blah", "more junk"
    ]
},

1 个答案:

答案 0 :(得分:4)

如果订单无关紧要,您可以使用set / set comprehension来获得所需的结果 -

def get_uniq_by_value(data, val_name):
    return {val for value in data.values() for val in value.get(val_name,[])}

如果您希望列表作为结果,则可以使用list()而不是设置理解将结果集转换为列表,然后再返回。

演示 -

>>> def get_uniq_by_value(data, val_name):
...     return {val for value in data.values() for val in value.get(val_name,[])}
...
>>> data = {
... "top1": {
...     "key1": [
...         "there is no spoon", "but dictionaries are hard",
...     ],
...     "key2": [
...         "mad max fury road was so good",
...     ]
... },
... "top2": {
...     "key1": [
...         "my item", "foo bar"
...     ],
...     "key2": [
...         "blah", "more junk"
...     ]
... }}
>>> get_uniq_by_value(data,"key1")
{'but dictionaries are hard', 'my item', 'foo bar', 'there is no spoon'}

如下面的评论中所示,如果订单很重要且data已经collections.OrderedDict OrderedDict,您可以使用新的OrderedDict,并添加列表中的元素作为键,OrderedDict将避免任何重复并保留添加键的顺序。

您可以使用评论中指示的OrderedDict.fomkeys在一行中执行此操作。示例 -

from collections import OrderedDict
def get_uniq_by_value(data, val_name):
    return list(OrderedDict.fromkeys(val for value in data.values() for val in value.get(val_name,[])))

请注意,这仅适用于data是嵌套的OrderedDict,因为否则data的元素根本不会以任何特定顺序开始。

演示 -

>>> from collections import OrderedDict
>>> data = OrderedDict([
... ("top1", OrderedDict([
...     ("key1", [
...         "there is no spoon", "but dictionaries are hard",
...     ]),
...     ("key2", [
...         "mad max fury road was so good",
...     ])
... ])),
... ("top2", OrderedDict([
...     ("key1", [
...         "my item", "foo bar"
...     ]),
...     ("key2", [
...         "blah", "more junk"
...     ])
... ]))])
>>>
>>> def get_uniq_by_value(data, val_name):
...     return list(OrderedDict.fromkeys(val for value in data.values() for val in value.get(val_name,[])))
...
>>> get_uniq_by_value(data,"key1")
['there is no spoon', 'but dictionaries are hard', 'my item', 'foo bar']