user132520
user132520

Reputation: 151

List Indices Must Be Integers or Slices, not Dict

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

Answers (3)

mhawke
mhawke

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

glls
glls

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

gipsy
gipsy

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

Related Questions