我对 Python/编程完全陌生,所以如果我做了什么愚蠢的事情或使用了错误的方法来解决问题,请多多包涵。
我想做的是搜索/比较字典列表,如果所有键 1-3 匹配,则返回“名称”,如果没有匹配,则返回不匹配。
有没有办法解决这个问题,或者如果没有,还有什么替代方法?
下面是一个例子:
从文件中读取数据库,转换成字典列表
[{'name': 'Albus', 'Key1': 15, 'Key2': 49, 'Key3': 38},
{'name': 'Cedric', 'Key1': 31, 'Key2': 21, 'Key3': 41},
...
{'name': 'Hagrid', 'Key1': 25, 'Key2': 38, 'Key3': 45}]
从文件中读取的输入,转换成dict
{'Key1': 15, 'Key2': 49, 'Key3': 38}
所需的输出:
Albus
答案 0 :(得分:3)
使用新的 Structural Pattern Matching introduced in python 3.10 和 for-else control flow 的 Python 3.10+ 答案:
data = [{'name': 'Albus', 'Key1': 15, 'Key2': 49, 'Key3': 38},
{'name': 'Cedric', 'Key1': 31, 'Key2': 21, 'Key3': 41},
{'name': 'Hagrid', 'Key1': 25, 'Key2': 38, 'Key3': 45}]
to_match = {'Key1': 15, 'Key2': 49, 'Key3': 38}
for dct in data:
match dct:
case {'name': name, **to_match}:
print(name)
break
else:
print(None)
输出:
Albus
当然,对于旧版本,可以这样重构:
for dct in data:
name = dct['name'] #[1]
if {'name': name, **to_match} == dct: #[2]
print(name)
break
else:
print(None)
注意: 在 Python 3.8+ 中,可以通过在第 [2] 行中使用 walsrus operator 来省略第 [1] 行,如下所示:
if {'name': (name := dct['name']), **to_match} == dct:
答案 1 :(得分:2)
您可以使用all()
:
lst = [
{"name": "Albus", "Key1": 15, "Key2": 49, "Key3": 38},
{"name": "Cedric", "Key1": 31, "Key2": 21, "Key3": 41},
{"name": "Hagrid", "Key1": 25, "Key2": 38, "Key3": 45},
]
dct = {"Key1": 15, "Key2": 49, "Key3": 38}
for d in lst:
if all(i in d.items() for i in dct.items()):
print(d["name"])
打印:
Albus
答案 2 :(得分:1)
target_name = None
for d in list_of_dicts:
if (target_dict['Key1']==d['Key1']) and (target_dict['Key2']==d['Key2']) and (target_dict['Key3']==d['Key3']):
target_name = d['name']
答案 3 :(得分:1)
如果您要进行大量此类查找,我可能建议您创建另一个字典来充当索引。
>>> db = [{'name': 'Albus', 'Key1': 15, 'Key2': 49, 'Key3': 38},
... {'name': 'Cedric', 'Key1': 31, 'Key2': 21, 'Key3': 41},
... {'name': 'Hagrid', 'Key1': 25, 'Key2': 38, 'Key3': 45}]
>>> index_123 = {(d['Key1'], d['Key2'], d['Key3']): d for d in db}
>>> query = {'Key1': 15, 'Key2': 49, 'Key3': 38}
>>>
>>> index_123[tuple(query.values())]['name']
'Albus'