Python 在字典列表中查找项
假设我有一个字典列表。 列表中的每个dict都有3个元素。 姓名、id和状态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':
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而言是如此),以便与代码的其他部分兼容。