4

在 Python 中,我有一个字典列表,如下所示:

matchings = [
    {'id': 'someid1', 'domain': 'somedomain1.com'},
    {'id': 'someid2', 'domain': 'somedomain2.com'},
    {'id': 'someid3', 'domain': 'somedomain3.com'}
]

而且,我有一个变量:

the_id = 'someid3'

检索项目域值的最有效方法是什么?

4

5 回答 5

6

您可以使用列表理解

domains = [matching['domain'] for matching in matchings if matching['id'] == the_id]

遵循以下格式标准格式:

resulting_list = [item_to_return for item in items if condition]

并且基本上封装了以下所有功能:

domains = []
for matching in matchings:
    if matching['id'] == the_id:
        domains.append(matching['domain'])

所有这些功能都使用列表推导在一行中表示。

于 2009-01-16T19:47:57.093 回答
2

我会重组matchings

from collections import defaultdict
matchings_ix= defaultdict(list)
for m in matchings:
    matchings_ix[m['id']].append( m )

现在最有效的查找是

matchings_ix[ d ]
于 2009-01-16T20:16:04.353 回答
1

我能想到的最好的办法是进行明确的搜索。这是我对 Python 感到失望的一个方面,它没有像 C++ STL 算法那样为您提供一组强大的解耦构建块

[d["domain"] for d in matchings if d["id"] == "someid3"]
于 2009-01-16T19:52:12.653 回答
0

列表中存在字典这一事实并不重要 - 问题归结为在列表中查找某个属性为真的项目。为此,@Soviut 的答案的一些变化是要走的路:循环或列表理解,检查每个项目直到找到匹配项。项目没有固有的顺序,所以你甚至不能依赖像bisect这样有用的东西。

于 2009-01-16T19:49:47.760 回答
0

我真的很喜欢在这种情况下使用过滤器。它接受一个函数和一个可迭代对象,并返回函数返回 True 的元素列表(在 Python 3.x 中它返回一个迭代器)。

>>> filter(lambda x: x['id'] == 'someid3', matchings)
<<< [{'domain': 'somedomain3.com', 'id': 'someid3'}]

您可以使用列表推导获得所有域的列表:

>>> [x['domain'] for x in filter(lambda x: x['id'] == 'someid3', matchings)]
<<< ['somedomain3.com']
于 2011-03-31T16:52:26.027 回答