Python 通过匹配字典的值,在列表中查找字典的索引

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/4391697/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-18 15:33:14  来源:igfitidea点击:

Find the index of a dict within a list, by matching the dict's value

python

提问by ensnare

I have a list of dicts:

我有一个字典列表:

list = [{'id':'1234','name':'Jason'},
        {'id':'2345','name':'Tom'},
        {'id':'3456','name':'Art'}]

How can I efficiently find the index position [0],[1], or [2] by matching on name = 'Tom'?

如何通过匹配 name = 'Tom' 有效地找到索引位置 [0]、[1] 或 [2]?

If this were a one-dimensional list I could do list.index() but I'm not sure how to proceed by searching the values of the dicts within the list.

如果这是一个一维列表,我可以执行 list.index() 但我不确定如何通过搜索列表中的 dicts 值来继续。

采纳答案by tokland

tom_index = next((index for (index, d) in enumerate(lst) if d["name"] == "Tom"), None)
# 1

If you need to fetch repeatedly from name, you should index them by name (using a dictionary), this way getoperations would be O(1) time. An idea:

如果您需要从名称中重复获取,则应按名称(使用字典)对它们进行索引,这样获取操作的时间将是 O(1)。一个主意:

def build_dict(seq, key):
    return dict((d[key], dict(d, index=index)) for (index, d) in enumerate(seq))

info_by_name = build_dict(lst, key="name")
tom_info = info_by_name.get("Tom")
# {'index': 1, 'id': '2345', 'name': 'Tom'}

回答by aeter

It won't be efficient, as you need to walk the list checking every item in it (O(n)). If you want efficiency, you can use dict of dicts. On the question, here's one possible way to find it (though, if you want to stick to this data structure, it's actually more efficient to use a generatoras Brent Newey has written in the comments; see also tokland's answer):

它不会高效,因为您需要遍历列表检查其中的每个项目(O(n))。如果你想要效率,你可以使用dict of dicts。关于这个问题,这里有一种可能的方法来找到它(不过,如果你想坚持这种数据结构,实际上使用生成器更有效,正如 Brent Newey 在评论中所写的那样;另见 tokland 的回答):

>>> L = [{'id':'1234','name':'Jason'},
...         {'id':'2345','name':'Tom'},
...         {'id':'3456','name':'Art'}]
>>> [i for i,_ in enumerate(L) if _['name'] == 'Tom'][0]
1

回答by Emile

A simple readable version is

一个简单易读的版本是

def find(lst, key, value):
    for i, dic in enumerate(lst):
        if dic[key] == value:
            return i
    return -1

回答by martineau

Here's a function that finds the dictionary's index position if it exists.

这是一个查找字典索引位置(如果存在)的函数。

dicts = [{'id':'1234','name':'Jason'},
         {'id':'2345','name':'Tom'},
         {'id':'3456','name':'Art'}]

def find_index(dicts, key, value):
    class Null: pass
    for i, d in enumerate(dicts):
        if d.get(key, Null) == value:
            return i
    else:
        raise ValueError('no dict with the key and value combination found')

print find_index(dicts, 'name', 'Tom')
# 1
find_index(dicts, 'name', 'Ensnare')
# ValueError: no dict with the key and value combination found

回答by michael salmon

Seems most logical to use a filter/index combo:

使用过滤器/索引组合似乎最合乎逻辑:

names=[{}, {'name': 'Tom'},{'name': 'Tony'}]
names.index(filter(lambda n: n.get('name') == 'Tom', names)[0])
1

And if you think there could be multiple matches:

如果您认为可能有多个匹配项:

[names.index(n) for item in filter(lambda n: n.get('name') == 'Tom', names)]
[1]

回答by pylang

For a given iterable, more_itertools.locateyields positions of items that satisfy a predicate.

对于给定的可迭代对象,more_itertools.locate产生满足谓词的项目的位置。

import more_itertools as mit


iterable = [
    {"id": "1234", "name": "Jason"},
    {"id": "2345", "name": "Tom"},
    {"id": "3456", "name": "Art"}
]

list(mit.locate(iterable, pred=lambda d: d["name"] == "Tom"))
# [1]

more_itertoolsis a third-party library that implements itertools recipesamong other useful tools.

more_itertools是一个第三方库,它在其他有用的工具中实现了itertools 配方

回答by faham

One liner!?

一个班轮!?

elm = ([i for i in mylist if i['name'] == 'Tom'] or [None])[0]

回答by stanely

Answer offered by @faham is a nice one-liner, but it doesn't return the index to the dictionary containing the value. Instead it returns the dictionary itself. Here is a simple way to get: A list of indexes one or more if there are more than one, or an empty list if there are none:

@faham 提供的答案是一个很好的单行,但它不会将索引返回到包含该值的字典中。相反,它返回字典本身。这是一种简单的获取方法:如果有多个索引,则为一个或多个索引列表,如果没有,则为空列表:

list = [{'id':'1234','name':'Jason'},
        {'id':'2345','name':'Tom'},
        {'id':'3456','name':'Art'}]

[i for i, d in enumerate(list) if 'Tom' in d.values()]

Output:

输出:

>>> [1]

What I like about this approach is that with a simple edit you can get a list of both the indexes and the dictionaries as tuples. This is the problem I needed to solve and found these answers. In the following, I added a duplicate value in a different dictionary to show how it works:

我喜欢这种方法的一点是,通过简单的编辑,您可以获得索引和字典作为元组的列表。这是我需要解决的问题,并找到了这些答案。在下面,我在不同的字典中添加了一个重复值来展示它是如何工作的:

list = [{'id':'1234','name':'Jason'},
        {'id':'2345','name':'Tom'},
        {'id':'3456','name':'Art'},
        {'id':'4567','name':'Tom'}]

[(i, d) for i, d in enumerate(list) if 'Tom' in d.values()]

Output:

输出:

>>> [(1, {'id': '2345', 'name': 'Tom'}), (3, {'id': '4567', 'name': 'Tom'})]

This solution finds all dictionaries containing 'Tom' in any of their values.

此解决方案查找在其任何值中包含“Tom”的所有字典。

回答by RobtnoX

def search(itemID,list):
     return[i for i in list if i.itemID==itemID]