我想在字典中匹配字典数据。这个:
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],
}
}
答案 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方法)。但是,仅出于娱乐和学习目的,这是一个可能对爱好项目有用的解决方案。
我的解决方案基于之前的两个答案,我应该相信这些答案:
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']