假设我有这个:
[
{"name": "Tom", "age": 10},
{"name": "Mark", "age": 5},
{"name": "Pam", "age": 7}
]
通过搜索“Pam”作为名称,我想检索相关的字典:{name:“Pam”,年龄:7}
如何做到这一点?
假设我有这个:
[
{"name": "Tom", "age": 10},
{"name": "Mark", "age": 5},
{"name": "Pam", "age": 7}
]
通过搜索“Pam”作为名称,我想检索相关的字典:{name:“Pam”,年龄:7}
如何做到这一点?
当前回答
鸭子将比列表理解或过滤器快得多。它在你的对象上建立一个索引,这样查找就不需要扫描每一个项目。
PIP安装鸭
from ducks import Dex
dicts = [
{"name": "Tom", "age": 10},
{"name": "Mark", "age": 5},
{"name": "Pam", "age": 7}
]
# Build the index
dex = Dex(dicts, {'name': str, 'age': int})
# Find matching objects
dex[{'name': 'Pam', 'age': 7}]
结果:[{'name': 'Pam', 'age': 7}]
其他回答
people = [
{'name': "Tom", 'age': 10},
{'name': "Mark", 'age': 5},
{'name': "Pam", 'age': 7}
]
def search(name):
for p in people:
if p['name'] == name:
return p
search("Pam")
我的第一个想法是,你可能想要考虑为这些字典创建一个字典……举个例子,如果你要多次搜索它。
然而,这可能是一个不成熟的优化。有什么问题:
def get_records(key, store=dict()):
'''Return a list of all records containing name==key from our store
'''
assert key is not None
return [d for d in store if d['name']==key]
你必须遍历列表中的所有元素。没有捷径!
除非在其他地方保存了一个包含指向列表项的名称的字典,但这时必须处理从列表中弹出元素的后果。
为@FrédéricHamidi添加一点点。
如果你不确定字典列表中是否有键,这样做会有帮助:
next((item for item in dicts if item.get("name") and item["name"] == "Pam"), None)
这里提出的大多数(如果不是全部)实现都有两个缺陷:
他们假设只传递一个键来进行搜索,而对于复杂的字典,有更多的键可能是有趣的 它们假定所有传递用于搜索的键都存在于字典中,因此当KeyError不存在时,它们不会正确处理。
更新后的命题:
def find_first_in_list(objects, **kwargs):
return next((obj for obj in objects if
len(set(obj.keys()).intersection(kwargs.keys())) > 0 and
all([obj[k] == v for k, v in kwargs.items() if k in obj.keys()])),
None)
也许不是最python化的,但至少更安全一点。
用法:
>>> obj1 = find_first_in_list(list_of_dict, name='Pam', age=7)
>>> obj2 = find_first_in_list(list_of_dict, name='Pam', age=27)
>>> obj3 = find_first_in_list(list_of_dict, name='Pam', address='nowhere')
>>>
>>> print(obj1, obj2, obj3)
{"name": "Pam", "age": 7}, None, {"name": "Pam", "age": 7}
要点。