Reputation: 151
I am doing some operations that involves extracting data from a list where every element is a dictionary. Each dictionary contains two key-value pairs which are a string and then an int (i.e {'ID':0, 'Zip Code':9414}), and then a key-value pair where the key is a string, and then a list ({'Value':[0,0,1,1,0,1]})
I'm able to access the values inside that list in a dictionary in a list very easily. However, since there are a bunch of elements in the list, I have to use a for loop to go through it. Basically what my method does is check if a 1 is at index(user specified number) in that list in a dict in a list. If it is, it updates another list with the first two key-value pairs from the same dict.
So, like this:
import returnExternalList #this method returns a list generated by an external method
def checkIndex(b):
listFiltered = {}
listRaw = returnExternalList.returnList #runs the method "returnList", which will return the list
for i in listRaw:
if listRaw[i]['Value'][b] == 1:
filteredList.update({listRaw[i]['ID']: listRaw[i]['Zip Code']})
print(filteredList)
checkIndex(1)
returnExternalList.returnList:
[{'ID':1 ,'Zip Code':1 ,'Value':[0,1,0,0,1]},{'ID':2 ,'Zip Code':2 ,'Value':[0,0,0,0,0]},{'ID':3,'Zip Code':3 ,'Value':[0,1,1,1,0]},{'ID':4 ,'Zip Code':4 ,'Value':[1,0,0,0,0]}]
expected output:
[{1:1 , 3:3}]
I can access values in a list inside a dictionary inside a list outside of a for loop very simply just by doing this:
print(listRaw[0]['Value'][1]) would return 1, for example.
However, when attempting to replicate that behaviour with the for loop to check every single one in the list, I get the error:
TypeError: list indices must be integers or slices, not dict
What do I do?
EDIT: Since it was asked for, returnExternalList:
def returnList:
listExample = [{'ID':1 ,'Zip Code':1 ,'Value':[0,1,0,0,1]},{'ID':2 ,'Zip Code':2 ,'Value':[0,0,0,0,0]},{'ID':3,'Zip Code':3 ,'Value':[0,1,1,1,0]},{'ID':4 ,'Zip Code':4 ,'Value':[1,0,0,0,0]}]
return listExample
EDIT: I used two of the solutions offered below, and while it does get rid of the error (thank you!) the output is simply a blank dictionary.
Code:
for i in listRaw:
if i['Value'][b] == 1:
filteredList.update({i['ID']: i['Zip Code']})
or
for i in range(len(listRaw):
if listRaw[i]['Value'][b] == 1:
filteredList.update({listRaw[i]['ID']: listRaw[i]['Zip Code']})
EDIT:
It works now, the reason the list was empty was because I was comparing 1 to '1'. It's been fixed. Thank you.
Upvotes: 0
Views: 13608
Reputation: 87074
The problem is that when you do
for i in listRaw:
this does not give you a ist index in i
, it gives you an actual dictionary from the list. Each iteration of the loop will give you the next dictionary in the list. You can fix it by doing this:
def checkIndex(b):
filteredList = {}
listRaw = returnExternalList.returnList #runs the method "returnList", which will return the list
for d in listRaw:
if d['Value'][b] == 1:
filteredList.update({d['ID']: d['Zip Code']})
print(filteredList)
But the whole thing can be written more succinctly as a dictionary comprehension:
def checkIndex(b):
print({d['ID']: d['Zip Code'] for d in returnExternalList.returnList if d['Value'][b] == 1})
And I'd be inclined to have your function accept the list as an argument rather than accessing a global variable, and to return the result:
def check_index(index, return_list):
return {d['ID']: d['Zip Code'] for d in return_list if d['Value'][index] == 1}
>>> print(check_index(1, returnExternalList.returnList))
{1: 1, 3: 3}
Upvotes: 1
Reputation: 2403
Hint: to call listRaw[i] i must be an integer
listRaw[0]['Value'][1] == 1
but i is not 0 when you do the for loop.
in your attempt of doing
for i in range(len(listRaw))
,
your dict. is empty, because the length of (len(listRaw)) is...1 so your iterations are not really iterating over all your dictionary elements.
consider adding some prints within your code to help debug, this comes in very handy when starting
Upvotes: 0
Reputation: 3859
When you do
for i in listRaw:
The i
is not the index, it is the actual item in the list(in your case it is a dict)
So you don't have to do listRaw[i]
to get the item. i
itself is the item. Change your code accordingly
Upvotes: 5