我有一个很长的命令,看起来像这样:
OrderedDict([('JIRAUSER16100', {'name': 'john.smith', 'fullname': 'John Smith', 'email': '[email protected]', 'active': True}), ('JIRAUSER16300', {'name': 'susan.jones', 'fullname': 'Susan Jones', 'email': '[email protected]', 'active': True})])
我如何搜索此列表以根据键值匹配找到键值?例如,对于苏珊·琼斯,我想根据姓名值查找她的电子邮件?有没有一种Python方式可以找到它而不只是遍历整个字典?
目前,我只是在下面执行此操作,但是当我必须遍历该列表1000次时,它似乎效率很低。我很好奇是否有某种“查找”方法吗?
searchname = "susan.jones"
for user in my_ordered_dict.items():
if user[1]["name"] == searchname:
print(user[1]["email"])
如果要查找特定的匹配项,则必须遍历结构直到找到它,这样就不必遍历整个字典。
类似:
In [19]: d = OrderedDict([('JIRAUSER16100', {'name': 'john.smith', 'fullname': 'John Smith', 'email': '[email protected]',
...: 'active': True}), ('JIRAUSER16300', {'name': 'susan.jones', 'fullname': 'Susan Jones', 'email': '[email protected]
...: t', 'active': True})])
...:
In [20]: def find_entry_by_subkey(sub_key, sub_key_value, data):
...: for entry in data.values():
...: if entry[sub_key] == sub_key_value:
...: return entry
...:
In [21]: find_entry_by_subkey('email', '[email protected]', d)
Out[21]:
{'name': 'susan.jones',
'fullname': 'Susan Jones',
'email': '[email protected]',
'active': True
您可能会对此进行改进的两种方法。您说您的OrderedDict
确实很长,所以我建议您使用第一种方法,因为随着数据大小的增加,它很快就会比第二种方法更快。
1)使用Pandas:
In [1]: from collections import OrderedDict
In [2]: import pandas as pd
In [3]: d = OrderedDict([
...: ('JIRAUSER16100', {'name': 'john.smith',
...: 'fullname': 'John Smith',
...: 'email': '[email protected]',
...: 'active': True}),
...: ('JIRAUSER16300', {'name': 'susan.jones',
...: 'fullname': 'Susan Jones',
...: 'email': '[email protected]',
...: 'active': True})
...: ])
In [4]: df = pd.DataFrame(d).T
In [5]: df
Out[5]:
name fullname email active
JIRAUSER16100 john.smith John Smith [email protected] True
JIRAUSER16300 susan.jones Susan Jones [email protected] True
In [6]: df.loc[df['name'] == 'susan.jones', 'email'][0]
Out[6]: '[email protected]'
[从易于学习但虚弱到难以学习但强大的规模上,pandas
远远落后于后者。如果您不熟悉pandas
,这里有很多可打包的东西,因此,为了简洁起见,我不再赘述。但是,如果有更多解释会有所帮助,请随时对任何问题发表评论。
2)使用内置的next
功能
这将使您避免循环浏览整个词典。长话短说,您可以传递next
具有三元表达式的生成器,并且该生成器实际上会经过可迭代的过程,直到找到满足给定条件的first项。因此,就您而言,
next
会工作。这将为您节省遍历整个词典的时间,但是与选项1不同,它的速度取决于您要查找的条目在In [7]: next(entry['email'] for entry in d.values() if entry['name'] == 'susan.jones')
Out[7]: '[email protected]'
中的位置。除非您出于某种原因只需要坚持使用标准库,否则在任何大小合理的数据集上Pandas的速度都会更快。
希望这会有所帮助!