Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

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

Tags:

python

People also ask

How do you get the index of a dictionary in a list?

Use the list[index] function to get index numbers from the dictionary. It will return the key and also use the items() function to return a collection from a dictionary.

Is dict () the same as {}?

The setup is simple: the two different dictionaries - with dict() and {} - are set up with the same number of elements (x-axis). For the test, each possible combination for an update is run.

How do I search a list in dictionary?

We can easily search a list of dictionaries for an item by using the filter() function with a lambda function. In Python3, the filter() function returns an object of the filter class. We can convert that object into a list with the list() function.


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

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 get operations would be O(1) time. An idea:

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

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

A simple readable version is

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

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 generator as Brent Newey has written in the comments; see also tokland's answer):

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

Seems most logical to use a filter/index combo:

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

And if you think there could be multiple matches:

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