Reputation: 33
So let's say I have AllData, a list of nested dicts (let's pretend there are thousands of entries) but I'm only looking for a single entry.
AllData = [
{ "EntryA" : {"A Key":"A Value"} },
{ "EntryB" : {"B Key":"B Value"} },
{ "EntryC" : {"C Key":"C Value"} }
]
Currently I'm just looping through it and breaking once I find the matching key.
MyKey = "EntryB"
FoundData = {}
for item in AllData:
for key,data in item.items():
if MyKey.lower() == key.lower():
FoundData = data
break
print(FoundData)
However, being a Python enthusiast I know there's a more elegant way to do this. I've struggled a bit with proper list comprehension techniques but I'm trying! Below is the best I've been able to come up with that gathers this data in a single line but I'm wondering if there is an even MORE elegant solution to this problem.
MyKey = "EntryB"
FoundData = [x for x in AllData if str(list(x.items())[0][0]).lower() == MyKey.lower()][0][MyKey]
print(FoundData)
Any insight would be greatly appreciated :)
Upvotes: 2
Views: 67
Reputation: 2702
I don't think a list comprehension is the appropriate way of doing this, since you only want the first match.
all_data = [
{"EntryA": {"A Key": "A Value"}},
{"EntryB": {"B Key": "B Value"}},
{"EntryC": {"C Key": "C Value"}}
]
targ_key = "EntryB"
found_data = None
for curr_dict in all_data:
if found_data := curr_dict.get(targ_key):
break
print(found_data)
I'm still not entirely sure if using an assignment expression here is worth it, it might make it more difficult to understand.
Here is a version without the assignment expression:
all_data = [
{"EntryA": {"A Key": "A Value"}},
{"EntryB": {"B Key": "B Value"}},
{"EntryC": {"C Key": "C Value"}}
]
targ_key = "EntryB"
found_data = None
for curr_dict in all_data:
curr_data = curr_dict.get(targ_key)
if curr_data is not None:
found_data = curr_data
break
print(found_data)
Upvotes: 1
Reputation: 194
You could use filter()
, depending on the contens of MyKey, it will look something as:
AllData = [
{ "EntryA" : {"A Key":"A Value"} },
{ "EntryB" : {"B Key":"B Value"} },
{ "EntryC" : {"C Key":"C Value"} }
]
MyKey = "EntryB"
found = list(filter(lambda x: MyKey in x.keys(), AllData))[0][MyKey]
print(found)
Upvotes: 0
Reputation: 195553
If you're using Python 3.8+ you can combine assignment expression (:=
) and any()
(any()
will break when you find first valid element):
AllData = [
{ "EntryA" : {"A Key":"A Value"} },
{ "EntryB" : {"B Key":"B Value"} },
{ "EntryC" : {"C Key":"C Value"} }
]
if any((found:=d) for d in AllData if "EntryB" in d):
print(found)
Prints:
{'EntryB': {'B Key': 'B Value'}}
Upvotes: 3