4

If I have a list with some nested dictionaries each containing the same keyset and value type set.

list = [{'a': 1, 'b': 2.0, 'c': 3.0}, 
        {'a': 4, 'b': 5.0, 'c': 6.0}, 
        {'a': 7, 'b': 8.0, 'c': 9.0}]

What is the most pythonic way to return the list index of the first of occurrence of 5.0 within the 'b' dictionary keys, or None if nothing is found?

I know I could iterate and search manually:

#with the list above...

result = None
for dict in list:
  if dict['b'] == 5.0:
    result = list.index(dict)
    break
print result
#(prints 1)


#as another example, same code but searching for a different value in 'b'
result = None
for dict in list:
  if dict['b'] == 6.0:
    result = list.index(dict)
    break
print result
#(prints None)

But this seems rather cumbersome. Thank you in advance.

Andrej Kesely
  • 168,389
  • 15
  • 48
  • 91
llealloo
  • 41
  • 2
  • 1
    Does this answer your question? [Python list of dictionaries search](https://stackoverflow.com/questions/8653516/python-list-of-dictionaries-search) – Andreas K. Dec 29 '19 at 20:17

3 Answers3

8

You can use next() builtin method (this will return None if nothing is found):

lst = [{'a': 1, 'b': 2.0, 'c': 3.0},
       {'a': 4, 'b': 5.0, 'c': 6.0},
       {'a': 7, 'b': 8.0, 'c': 9.0}]

print(next((i for i, d in enumerate(lst) if d['b'] == 5.0), None))

Prints:

1
Andrej Kesely
  • 168,389
  • 15
  • 48
  • 91
  • 1
    Thank you, this is much better – llealloo Dec 29 '19 at 20:20
  • @Andrej Kesely Nice pythonic solution but if `lst=[{'a': 1, 'b': 2.0, 'c': 3.0}, {'a': 4, 'b': 5.0, 'c': 6.0},{'a': 7, 'b': 8.0, 'c': 9.0},{'a': 4, 'b': 5.0, 'c': 6.0}]` your solution wil print only 1 but the correct answer is 1,3. – Ch3steR Dec 29 '19 at 20:47
  • @Ch3steR The question was "... What is the most pythonic way to return the list index of the **first of occurrence** ...". So the first occurrence is `1`. – Andrej Kesely Dec 29 '19 at 20:53
  • 1
    @andrej My bad sorry. – Ch3steR Dec 29 '19 at 20:55
2

You can filter your data using pandas.

Like this,

import pandas as pd

list = [{'a': 1, 'b': 2.0, 'c': 3.0}, 
    {'a': 4, 'b': 5.0, 'c': 6.0}, 
    {'a': 7, 'b': 8.0, 'c': 9.0}]

Put your list into a pandas dataframe,

df = pd.DataFrame(list)

your data

print(df.head())

   a    b    c
0  1  2.0  3.0
1  4  5.0  6.0
2  7  8.0  9.0

and then filter it

df = df[df.b==5]    

and your filtered data,

print(df.head())
   a    b    c
1  4  5.0  6.0

if there is no match, df will be an empty dataframe.

To get just the index,

df.index[df.b==5].tolist()
merit_2
  • 461
  • 5
  • 16
0

I make something, I think it will be more helpful as I understand from your question.

li = [{'a': 1, 'b': 2.0, 'c': 3.0},
      {'a': 4, 'b': 5.0, 'c': 6.0},
      {'a': 7, 'b': 8.0, 'c': 9.0}]


def find_first(num):
    for di in li:
        for k, v in di.items():
            if v == num:
                return li.index(di)
    else:
        return None


print(find_first(5))
Kevin Omar
  • 127
  • 9