简体   繁体   English

Python:如何访问列表中具有特定键值的字典

[英]Python: How to access the dictionary that has specific key-values in a list

I have a list of dictionaries: 我有一个词典列表:

[
{"START":"Denver", "END":"Chicago", "Num":0},
{"START":"Dallas", "END":"Houston", "Num":3},
{"START":"Virginia", "END":"Boston", "Num":1},
{"START":"Washington", "END":"Maine", "Num":7}
]

How do I access the dictionary in this list that has "START":"Virginia", "END":"Boston" in most pythonic way? 如何访问此列表中具有"START":"Virginia", "END":"Boston"的字典"START":"Virginia", "END":"Boston"以大多数pythonic方式?

The most Pythonic way is probably a list comprehension: 最恐怖的方式可能是列表理解:

[ d for d in dict_list if d["START"] == "Virginia" and d["END"] == "Boston" ]

As mgilson pointed out, if you are assuming that there's only one item in the list with that pair of locations, you can use next with the same generator expression, instead of the brackets. 作为mgilson指出,如果假设只有一个在与该对位置列表中的项目,您可以使用next具有相同发电机表达,而不是括号。 That will return just the matching dict, rather than a one-item list containing it: 这将返回匹配的dict,而不是包含它的单项列表:

trip = next( d for d in dict_list 
               if d["START"] == "Virginia" and d["END"] == "Boston" )

Either way, the result references the same dict object(s) as the original list, so you can make changes: 无论哪种方式,结果都引用与原始列表相同的dict对象,因此您可以进行更改:

trip["Num"] = trip["Num"] + 1

And those changes will be there when accessed through the original list: 当通过原始列表访问时,这些更改将在那里:

print(dict_list[2]["Num"])    # 2

As Ashwini Chaudhary indicated in his answer, your search may itself be specified as a dict. 正如Ashwini Chaudhary在他的回答中指出的那样,你的搜索本身可能被指定为词典。 In that case, the if condition in the generator expression is a little different, but the logic is otherwise the same: 在这种情况下,生成器表达式中的if条件稍有不同,但逻辑在其他方面是相同的:

search = { "START": "Virginia", "END": "Boston" }
trip = next(d for d in dict_list if all(i in d.items() for i in search.items()))

use all() with dict.items() : dict.items()使用all() dict.items()

In [66]: lis=[                                      
   ....: {"START":"Denver", "END":"Chicago", "Num":0},
   ....: {"START":"Dallas", "END":"Houston", "Num":3},
   ....: {"START":"Virginia", "END":"Boston", "Num":1},
   ....: {"START":"Washington", "END":"Maine", "Num":7}
   ....: ]

In [67]: for x in lis:                              
   ....:         if all(y in x.items() for y in search.items()):
   ....:                 x['Num']="foobar"        #change Num here
   ....:         

In [68]: lis
Out[68]: 
[{'END': 'Chicago', 'Num': 0, 'START': 'Denver'},
 {'END': 'Houston', 'Num': 3, 'START': 'Dallas'},
 {'END': 'Boston', 'Num': 'foobar', 'START': 'Virginia'},
 {'END': 'Maine', 'Num': 7, 'START': 'Washington'}]

using a list comprehension : 使用list comprehension

In [58]: [x for x in lis if all(y in x.items() for y in search.items())]
Out[58]: [{'END': 'Boston', 'Num': 1, 'START': 'Virginia'}]

If you are going to do the search a lot of times and you know there is one and only one dict for every pair of locations you could create a dict from the list like this: 如果你要进行很多次搜索,并且你知道每对位置都有一个且只有一个dict,你可以从列表中创建一个dict,如下所示:

d = dict(((x['START'], x['END']), x) for x in list_of_dicts)

And then just do lookups in the new dict like this: 然后在新的字典中进行查找,如下所示:

found_dict = d[('Virginia', 'Chicago')]

You could change found_dict then however you need. 您可以根据需要更改found_dict

If each item is unique, then you could do this: 如果每个项目都是唯一的,那么您可以这样做:

def get_dict(items, start, end):
    for dict in items:
        if dict['START'] == start and dict['END'] == end:
            return dict

And then: 接着:

>>> items = [
    {"START":"Denver", "END":"Chicago", "Num":0},
    {"START":"Dallas", "END":"Houston", "Num":3},
    {"START":"Virginia", "END":"Boston", "Num":1},
    {"START":"Washington", "END":"Maine", "Num":7}
]
>>> get_dict(items, 'Virginia', 'Boston')
{"START":"Virginia", "END":"Boston", "Num":1}

It's fairly straightforward, but I thought I'd post it for the sake of completeness. 它相当简单,但我认为我会为了完整性而发布它。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM