Python:字典中的字典,通配符第一个键

时间:2019-08-15 16:03:01

标签: python python-3.x

我想在字典中匹配字典数据。这个:

print(a["myval"]["val1"])

起作用以获得所需的输出。 但是,我想“通配” myval条目。还输出myval2

的结果
print(a['*']["val1"])

但这不起作用。

我当前的方法似乎很笨拙:

for i in iter(a):
       print(i)
       print(a[i]["val1"])

当我选择val3时,它也会中断。这是我的字典

a = {
        "myval" : {
                "val1" : True,
                "val2" : 1,
        },
        "myval2" : {
                "val1" : False,
                "val2" : 0,
                "val3" : [1, 2, 3],
        }
}

4 个答案:

答案 0 :(得分:6)

在Python中,指令不支持通配符。但是,您可以尝试执行以下操作:

desired_key = "val3"
vals = [ a[key][desired_key] for key in a.keys() if desired_key in a[key] ]

这将在某个第二层键下创建所有第二层元素的数组(如果该键存在)。

答案 1 :(得分:4)

您可以通过将a['*']设置为将用作通配符的函数来自己实现此版本。

def getAll(your_dict, search_for):
  values = []
  for key, value in your_dict.items():
    if type(value) == dict and  search_for in value:
      values.append(value[search_for])
  return values

a = {
        "myval" : {
                "val1" : True,
                "val2" : 1,
        },
        "myval2" : {
                "val1" : False,
                "val2" : 0,
                "val3" : [1, 2, 3],
        },
        "*": lambda key: getAll(a, key)
}

然后用

调用
a['*']('val1')  # >>> [True, False]

您正在将a['*']设置为一个函数,该函数将返回取自所有内部字典的值的数组。

答案 2 :(得分:4)

这是与迈克尔·比安科尼(Michael Bianconi)的答案类似的解决方案,它将使您可以完全按照以下方式使用结果对象:

class UniversalIndexer:
    def __init__(self, dct):
        self.dct = dct

    def __getitem__(self, item):
        return [self.dct[key][item] for key in self.dct if key != "*"]

a = {
    "myval" : {
        "val1" : True,
        "val2" : 1,
    },
    "myval2" : {
        "val1" : False,
        "val2" : 0,
        "val3" : [1, 2, 3],
    }
}
a["*"] = UniversalIndexer(a)

答案 3 :(得分:1)

正如已经讲过的,词典本身并不支持通配符,通常我不建议使用这种方法(tituszban的答案是简单直接的Pythonic方法)。但是,仅出于娱乐和学习目的,这是一个可能对爱好项目有用的解决方案。

我的解决方案基于之前的两个答案,我应该相信这些答案:

  • Michael Bianconi编写了第一个解决方案:将方法手动添加到每个字典实例。结果应使用函数而不是索引(它会改变预期的使用方式恕我直言)。
  • L3viathan通过返回自定义UniversalIndexer对象而不是函数来改进了此解决方案,从而模仿了字典的正常使用。

我进一步扩展了此解决方案,以创建一个MultiDict类,该类的行为类似于普通字典,但是覆盖了星号的行为。因此,您无需为每个实例手动添加它。另一个优点是字典实际上并不包含额外的'*'键,因此对其进行迭代仍然可以按预期进行(即,您不必过滤掉此特殊键)。我还实现了__setitem__()方法,以便您可以使用通配符分配值。

class UniversalIndexer:

    def __init__(self, dct):
        self.dct = dct

    def __getitem__(self, key):
        return [self.dct[dkey][key] for dkey in self.dct]

    def __setitem__(self, key, value):
        for dkey in self.dct:
            self.dct[dkey][key] = value


class MultiDict(dict):

    def __getitem__(self, key):
        if key == '*':
            return UniversalIndexer(self)
        return dict.__getitem__(self, key)


# TEST/DEMONSTRATION CODE:

a = MultiDict({
    'myval': {
        'val1': True,
        'val2': 1,
    },
    'myval2': {
        'val1': False,
        'val2': 0,
        'val3': [1, 2, 3],
    }
})

print(a['myval']['val1'])  # True
print(a['*']['val1'])      # [True, False]

a['*']['val4'] = 10
print(a['*']['val4'])      # [10, 10]
print(list(a.keys()))      # ['myval', 'myval2']