如何访问字典中的所有字典,其中特定键具有特定值

时间:2017-01-10 10:20:10

标签: python dictionary

我有一本字典词典,每个嵌套字典都有完全相同的键,如下所示:

all_dicts = {'a':{'name': 'A', 'city': 'foo'},
             'b':{'name': 'B', 'city': 'bar'},
             'c':{'name': 'C', 'city': 'bar'},
             'd':{'name': 'B', 'city': 'foo'},
             'e':{'name': 'D', 'city': 'bar'},
            }

如何获取'city'具有值'bar'的所有词典的列表(或词典)?

以下代码有效,但不可扩展:

req_key = 'bar'
selected = []
for one in all_dicts.keys():
    if req_key in all_dicts[one]:
    selected.append(all_dicts[one])

'city'可以有50,000个唯一值,而字典all_dicts包含600,000个值,因为'city'的每个值都在字典上迭代效率不高。

是否有可扩展且有效的方法?

4 个答案:

答案 0 :(得分:9)

您可以做的是在该字典上创建索引,如下所示:

cityIndex={}
for item in all_dicts.values():
    if item['city'] in cityIndex:
        cityIndex[item['city']].append(item)
    else:
        cityIndex[item['city']]=[item]

这将需要一些初始处理时间以及一些额外的内存,但之后它会非常快。如果您想要所有带有cityName项的项目,您可以通过以下方式获取它们:

mylist=cityIndex[cityName] if cityName in cityIndex else []

如果all_dicts构建一次并在之后多次查询,这将为您带来许多好处。

如果在执行程序期间修改all_dicts,则需要更多代码来维护cityIndex。如果将item添加到all_dicts,请执行以下操作:

if item['city'] in cityIndex:
    cityIndex[item['city']].append(item)
else:
    cityIndex[item['city']]=[item]

如果项目被删除,这也是一种直接从索引中删除它的方法(假设'name'和'city'的组合在您的项目中是唯一的):

for i, val in enumerate(cityIndex[item['city']]):
    if val['name']==item['name']:
        break
del cityIndex[item['city']][i]

如果查询比更新更多,您仍然可以获得巨大的性能提升。

答案 1 :(得分:7)

您必须检查所有值;没有替代方案。然而,您可以使用矢量化方法 - 列表理解 - 这将比for循环快得多:

selected = [d for d in all_dicts.values() if d['city']=='bar']
print(selected)
# [{'name': 'B', 'city': 'bar'}, {'name': 'C', 'city': 'bar'}, {'name': 'D', 'city': 'bar'}]

使用dict.values而不是访问字典键也可以提高性能,并且在Python 3中也具有内存效率。

答案 2 :(得分:3)

或者在python 3中使用filter

>>> list(filter(lambda x: x['city']=='bar', all_dicts.values()))
# [{'name': 'D', 'city': 'bar'}, {'name': 'B', 'city': 'bar'}, {'name': 'C', 'city': 'bar'}]

pandas

import pandas as pd

df = pd.DataFrame(all_dicts).T
df[df.city=='bar'].T.to_dict()

# {'e': {'city': 'bar', 'name': 'D'}, 'c': {'city': 'bar', 'name': 'C'}, 'b': {'city': 'bar', 'name': 'B'}}

答案 3 :(得分:0)

all_dicts = {'a':{'name': 'A', 'city': 'foo'},
             'b':{'name': 'B', 'city': 'bar'},
             'c':{'name': 'C', 'city': 'bar'},
             'd':{'name': 'B', 'city': 'foo'},
             'e':{'name': 'D', 'city': 'bar'},
            }

citys = {}
for key, value in all_dicts.items():
    citys[key] = value['city']
#{'a': 'foo', 'b': 'bar', 'e': 'bar', 'd': 'foo', 'c': 'bar'}

for key, value in citys.items():
    if value == 'bar':
        print(all_dicts[key])

出:

{'name': 'B', 'city': 'bar'}
{'name': 'D', 'city': 'bar'}
{'name': 'C', 'city': 'bar'}

构建辅助字典以将城市存储为索引,您可以非常快速地引用它。