Python 在字典列表中查找项

Python 在字典列表中查找项,python,list,dictionary,Python,List,Dictionary,假设我有一个字典列表。 列表中的每个dict都有3个元素。 姓名、id和状态 list_of_dicts = [{'id':1, 'name':'Alice', 'status':0},{'id':2, 'name':'Bob', 'status':0},{'id':3, 'name':'Robert', 'status':1}] 所以我得到: In[20]: print list_of_dicts Out[20]: [{'id': 1, 'name': 'Alice', 'status':

假设我有一个字典列表。 列表中的每个dict都有3个元素。 姓名、id和状态

list_of_dicts = [{'id':1, 'name':'Alice', 'status':0},{'id':2, 'name':'Bob', 'status':0},{'id':3, 'name':'Robert', 'status':1}]
所以我得到:

In[20]: print list_of_dicts
Out[20]: 
[{'id': 1, 'name': 'Alice', 'status': 0},
 {'id': 2, 'name': 'Bob', 'status': 0},
 {'id': 3, 'name': 'Robert', 'status': 1}]
如果我收到一个名字,我如何在不重复列表的情况下获得它的状态?

例如,我得到“Robert”,我想输出1。
谢谢。

如果不反复阅读字典,我想你不能做你想做的事:
最好的情况是,你会发现有人建议你一个隐藏迭代的方法

如果您真正关心的是速度,那么您可能会在找到第一个有效结果后立即中断迭代:

for iteration, elements in enumerate(list_of_dicts):
    if elements['name'] == "Robert":
        print "Elements id: ", elements['id']
        break
print "Iterations: ", iteration

# OUTPUT: Elements id: 3, Iterations: 1

请注意,迭代次数可能会有所不同,因为字典没有索引,如果您有更多的
“Roberts”
,只有一个
“id”
将被打印出来如果没有迭代,这是不可能的

但是,您可以将词典转换为不同的数据结构,例如名称为键的词典:

new_dict = {person["name"]: {k: v for k, v in person.items() if k != "name"} for person in list_of_dicts}
然后您可以获得如下状态:

new_dict["Robert"]["status"]
# 1
此外,如评论中所述,您可以保持内部词典不变:

{person["name"]: person for person in list_of_dicts}
上述方法的唯一问题是它不能处理多个名称。您可以将唯一id添加到密钥中以区分名称:

new_dict = {(person["name"], person["id"]): person["status"] for person in list_of_dicts}
可以这样称呼:

new_dict["Robert", 3]
# 1

尽管创建这些数据结构需要额外的计算(只需一次),但之后的查找将是O(1),而不是每次搜索名称时都迭代列表

例如,您可以使用熊猫

import pandas as pd
list_of_dicts = [{'id':1, 'name':'Alice', 'status':0},{'id':2, 'name':'Bob', 'status':0},{'id':3, 'name':'Robert', 'status':1}]

a = pd.DataFrame(list_of_dicts)
a.loc[a['name'] == 'Robert']

和使用DeFaFrims非常快,因为在C++上写的很简单(就像SQL查询)

,因为你发现你必须迭代(除非你能够改变你的数据结构到一个封闭的DICT)你为什么不去做?
>>> [d['status'] for d in list_of_dicts if d['name']=='Robert']
[1]

尽管如此,我还是建议每次在建议的数据结构中看到一些“id”字段时,都考虑使用映射类型(比如dict)。如果它在那里,你可能想用它来做一般的识别,而不是随身携带口述。它们也可以用于关系,如果您以后需要,可以很容易地传输到关系数据库。

如果没有循环,您的
目录列表将无法访问,因此,出于您的需要,您的列表应该修改为有点像1个目录和其中的许多列表:

list_of_dicts_modified = {'name':['Alice', 'Bob', 'Robert'],'id':[1, 2, 3], 'status': [0, 0, 1]}
index = list_of_dicts_modified['name'].index(input().strip())
print('Name: {0} ID: {1} Status: {2}'.format(list_of_dicts_modified['name'][index], list_of_dicts_modified['id'][index], list_of_dicts_modified['status'][index]))
输出:

C:\Users\Documents>py test.py
Alice
Name: Alice ID: 1 Status: 0

除非您将初始的
lod
转换为不同的数据结构,否则无法进行转换,这本身就需要迭代。如果您必须查询多个名称,那么这可能仍然更可取。我认为如果不在列表上进行迭代,您无法做到这一点。如果您必须多次进行搜索,那么将数据结构转换为
{'Alice':0,'Bob':0,'Robert':1}
可能是值得的。“那么你只迭代一次。”博阿古利斯同意。如果有重复的名称,您可能必须在查询/键中包含
id
。也许您应该使用dict of dict(而不是dict列表)并使用{name}{id}作为键,我看到了,所以如果我必须迭代,您会建议如何做?这是我的建议。添加:可以使用自定义类简化问题。谢天谢地,Pandas已经通过
pd.DataFrame
提供了这样一个类,因此您不需要重新发明轮子。我建议只使用
{person[“name”]:dicts列表中的person-for-person}
,因此内部dicts仍然采用相同的格式(事实上,
新dicts.values()
与dicts的列表基本相同,至少对于较新版本的Python而言是如此),以便与代码的其他部分兼容。