Python Find matching item in a list of dictionaries
Question:
I have a big list of dictionaries. Each dictionary contains timeseries data of each sensor when each data point is collected. I want to know the index location of a specific sensor and date. So, I can update the sensor value.
My code:
big_list = [
dict({'sensor':12,'time':'2022-02-03','value':10}),
dict({'sensor':22,'time':'2022-02-03','value':12}),
dict({'sensor':32,'time':'2022-02-03','value':24}),
dict({'sensor':12,'time':'2022-02-04','value':17}),
dict({'sensor':22,'time':'2022-02-04','value':13}),
dict({'sensor':32,'time':'2022-02-04','value':21})]
# Find index of an item
item_to_find = dict({'time':'2022-02-03','sensor':32})
# solution
big_list.index(item_to_find)
Present output:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: {'sensor': 32, 'time': '2022-02-03'} is not in list
Expected output:
2
Answers:
I know this may not be the most efficient solution, but it was the best I could do. 🙂
sensor = 32
time = '2022-02-03'
for item in big_list:
if item.get('sensor') == sensor and item.get('time') == time:
print(big_list.index(item))
You can try next()
+ enumerate()
:
idx = next(
i for i, d in enumerate(big_list) if all(d[k] == v for k, v in item_to_find.items())
)
print(idx)
Prints:
2
OR: You can add default parameter to next()
in case the item is not found:
# returns None if the item is not found
idx = next(
(i for i, d in enumerate(big_list) if all(d[k] == v for k, v in item_to_find.items())), None
)
print(idx)
Try this:
list(
map(
lambda x: {'time': x['time'], 'sensor': x['sensor']} == item_to_find,
big_list
)
).index(True)
Explanation:
- use
map()
to extract the values to be compared, stripping away the value
- in the function being mapped, make the comparison with
item_to_find
– this will return an iterator which will yield True
for a match or False
for a non-match.
- turn the resulting iterator into a list with
list()
- find the first occurrence in this list of
True
and return the index.
You might also want to look at pandas
that makes all this a lot more easy to handle.
Same idea as @Andrej but you can use lambda function for clearer intention
same_time_and_sensor = lambda item: item['sensor'] == item_to_find['sensor'] and item['time'] == item_to_find['time']
index = next((i for i, item in enumerate(big_list) if same_time_and_sensor(item)), None)
print(index)
Here next()
will return index of the first match or None
if no match found.
If you are looking for a specific date
and sensor
you can make a loop to iterate over every dictionary in the list and save the index of matching item in the list of index:
sensor = 32
date = '2022-02-03'
ind = []
for idx, dt in enumerate(big_list):
if dt['sensor'] == sensor and dt['time'] == date:
ind.append(idx)
print(ind)
In the meantime, I found a online answer as well:
solution_item = next(filter(lambda s: s['time']==item_to_find['time'] and s['sensor']==item_to_find['sensor'],big_list))
{'sensor': 32, 'time': '2022-02-03', 'value': 24}
For index of the solution
big_list.index(solution_item)
2
I would recommend converting your list of dictionaries to a dataframe. Especially if you need to do this multiple times.
import pandas as pd
big_df = pd.DataFrame(big_list).reset_index()
i = big_df[(big_df['sensor']==32)&(big_df['time']=='2022-02-03')]['index'].item()
print(i)
I have a big list of dictionaries. Each dictionary contains timeseries data of each sensor when each data point is collected. I want to know the index location of a specific sensor and date. So, I can update the sensor value.
My code:
big_list = [
dict({'sensor':12,'time':'2022-02-03','value':10}),
dict({'sensor':22,'time':'2022-02-03','value':12}),
dict({'sensor':32,'time':'2022-02-03','value':24}),
dict({'sensor':12,'time':'2022-02-04','value':17}),
dict({'sensor':22,'time':'2022-02-04','value':13}),
dict({'sensor':32,'time':'2022-02-04','value':21})]
# Find index of an item
item_to_find = dict({'time':'2022-02-03','sensor':32})
# solution
big_list.index(item_to_find)
Present output:
Traceback (most recent call last):
File "<stdin>", line 1, in <module>
ValueError: {'sensor': 32, 'time': '2022-02-03'} is not in list
Expected output:
2
I know this may not be the most efficient solution, but it was the best I could do. 🙂
sensor = 32
time = '2022-02-03'
for item in big_list:
if item.get('sensor') == sensor and item.get('time') == time:
print(big_list.index(item))
You can try next()
+ enumerate()
:
idx = next(
i for i, d in enumerate(big_list) if all(d[k] == v for k, v in item_to_find.items())
)
print(idx)
Prints:
2
OR: You can add default parameter to next()
in case the item is not found:
# returns None if the item is not found
idx = next(
(i for i, d in enumerate(big_list) if all(d[k] == v for k, v in item_to_find.items())), None
)
print(idx)
Try this:
list(
map(
lambda x: {'time': x['time'], 'sensor': x['sensor']} == item_to_find,
big_list
)
).index(True)
Explanation:
- use
map()
to extract the values to be compared, stripping away thevalue
- in the function being mapped, make the comparison with
item_to_find
– this will return an iterator which will yieldTrue
for a match orFalse
for a non-match. - turn the resulting iterator into a list with
list()
- find the first occurrence in this list of
True
and return the index.
You might also want to look at pandas
that makes all this a lot more easy to handle.
Same idea as @Andrej but you can use lambda function for clearer intention
same_time_and_sensor = lambda item: item['sensor'] == item_to_find['sensor'] and item['time'] == item_to_find['time']
index = next((i for i, item in enumerate(big_list) if same_time_and_sensor(item)), None)
print(index)
Here next()
will return index of the first match or None
if no match found.
If you are looking for a specific date
and sensor
you can make a loop to iterate over every dictionary in the list and save the index of matching item in the list of index:
sensor = 32
date = '2022-02-03'
ind = []
for idx, dt in enumerate(big_list):
if dt['sensor'] == sensor and dt['time'] == date:
ind.append(idx)
print(ind)
In the meantime, I found a online answer as well:
solution_item = next(filter(lambda s: s['time']==item_to_find['time'] and s['sensor']==item_to_find['sensor'],big_list))
{'sensor': 32, 'time': '2022-02-03', 'value': 24}
For index of the solution
big_list.index(solution_item)
2
I would recommend converting your list of dictionaries to a dataframe. Especially if you need to do this multiple times.
import pandas as pd
big_df = pd.DataFrame(big_list).reset_index()
i = big_df[(big_df['sensor']==32)&(big_df['time']=='2022-02-03')]['index'].item()
print(i)