I have the following list of dictionaries, with sub dictionaries data:
data2 = [
{"dep": None},
{"dep": {
"eid": "b3ca7ddc-0d0b-4932-816b-e74040a770ec",
"nid": "fae15b05-e869-4403-ae80-6e8892a9dbde",
}
},
{"dep": None},
{"dep": {
"eid": "c3bcaef7-e3b0-40b6-8ad6-cbdb35cd18ed",
"nid": "6a79c93f-286c-4133-b620-66d35389480f",
}
},
]
And I have a match key:
match_key = "b3ca7ddc-0d0b-4932-816b-e74040a770ec"
And I want to see if any sub dictionaries of each "dep" key in data2 have an eid that matches my match_key. I'm trying the following, but I get a TypeError: string indices must be integers - where am I going wrong?
My Code
matches = [
d["eid"]
for item in data2
if item["dep"]
for d in item["dep"]
if d["eid"] == match_key
]
So matches should return:
["b3ca7ddc-0d0b-4932-816b-e74040a770ec"]
Meaning it found this id in data2.
CodePudding user response:
When you iterate over a dictionary, each iteration gives you a key from the dictionary.
So d["eid"]
is actually "eid"["eid"]
, which is an invalid expression. That's why Python raises the following exception:
TypeError: string indices must be integers
Also, the expression d["eid"]
assumes that every d
contains the eid
key. If it doesn't, Python will raise a KeyError
.
If you don't know for sure that "eid" is a valid key in the dictionary, prefer using the .get
method instead.
matches = [
v
for item in data2
if item.get("dep") # Is there a key called dep, and it has a non-falsy value in it
for k, v in item["dep"].items() # Iterate over the dictionary items
if k == "eid" and v == match_key
]
You can do even better by directly accessing the value of eid
key:
matches = [
d["dep"]["eid"]
for d in data2
if d.get("dep") and d["dep"].get("eid") == match_key
]