Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

TypeError: 'int' object has no attribute '__getitem__' error because of possible erratum in book

Tags:

python

I'm going through the new book "Data Science from Scratch: First Principles with Python" and I think I've found an errata.

When I run the code I get "TypeError: 'int' object has no attribute '__getitem__'". I think this is because when I try to select friend["friends"], friend is an integer that I can't subset. Is that correct? How can I continue the exercises so that I get the desired output? It should be a list of friend of friends (foaf). I know there's repetition problems but those are fixed later...

users = [
    {"id": 0, "name": "Ashley"},
    {"id": 1, "name": "Ben"},
    {"id": 2, "name": "Conrad"},
    {"id": 3, "name": "Doug"},
    {"id": 4, "name": "Evin"},
    {"id": 5, "name": "Florian"},
    {"id": 6, "name": "Gerald"}
]

#create list of tuples where each tuple represents a friendships between ids
friendships = [(0,1), (0,2), (0,5), (1,2), (1,5), (2,3), (2,5), (3,4), (4,5), (4,6)]

#add friends key to each user 
for user in users:
    user["friends"] = []

#go through friendships and add each one to the friends key in users
for i, j in friendships:
    users[i]["friends"].append(j)
    users[j]["friends"].append(i)

def friends_of_friend_ids_bad(user): 
    #foaf is friend of friend
    return [foaf["id"]
        for friend in user["friends"]
        for foaf in friend["friends"]]

print friends_of_friend_ids_bad(users[0])

Full traceback:

Traceback (most recent call last):
  File "/Users/marlon/Desktop/test.py", line 57, in <module>
    print friends_of_friend_ids_bad(users[0])
  File "/Users/marlon/Desktop/test.py", line 55, in friends_of_friend_ids_bad
    for foaf in friend["friends"]]
TypeError: 'int' object has no attribute '__getitem__'
[Finished in 0.6s with exit code 1]
[shell_cmd: python -u "/Users/marlon/Desktop/test.py"]
[dir: /Users/marlon/Desktop]
[path: /usr/bin:/bin:/usr/sbin:/sbin]

How I think it can be fixed: I think you need users as a second argument and then do "for foaf in users[friend]["friends"]" instead of "for foaf in friend["friends"]

like image 380
megashigger Avatar asked May 29 '15 06:05

megashigger


1 Answers

Yes, you've found an incorrect piece of code in the book.

Implementation for friends_of_friend_ids_bad function should be like this:

def friends_of_friend_ids_bad(user): 
    #foaf is friend of friend
    return [users[foaf]["id"]
        for friend in user["friends"]
        for foaf in users[friend]["friends"]]

user["friends"] is a list of integers, thus friend is an integer and friend["friends"] will raise TypeError exception


UPD

It seems, that the problem in the book was not about friends_of_friend_ids_bad function but about populating friends lists.

Replace

for i, j in friendships:
    users[i]["friends"].append(j)
    users[j]["friends"].append(i)

with

for i, j in friendships:
    users[i]["friends"].append(users[j])
    users[j]["friends"].append(users[i])

Then friends_of_friend_ids_bad and friends_of_friend_ids will work as intended.

like image 63
Alik Avatar answered Nov 01 '22 13:11

Alik