85

I am new to python and couldn't find the answer to this. Referring to the code at the end of the message, can I know what does the part "for item, total in totals.items()" in the line below mean?

rankings = [(total/simSums[item], item) for item, total in totals.items()]

Also, the code failed and said

AttributeError: 'dict' object has no attribute 'predictors'

when I changed all instances of "item(s)" in the code to "predictor(s)". Why is that so?

# Return the Pearson correlation coefficient for p1 and p2
def sim_person(prefs, p1, p2):
    # Get the list of shared_items
    si={}
    for item in prefs[p1]:
        if item in prefs[p2]:si[item]=1

    # Find the number of elements 
    n=len(si)

    # if they have no ratings in common, return 0
    if n==0: return 0

    # Add up all the preferences
    sum1 = sum([prefs[p1][it] for it in si])
    sum2 = sum([prefs[p2][it] for it in si])

    # Sum up the squares
    sum1Sq = sum([pow(prefs[p1][it],2) for it in si])
    sum2Sq = sum([pow(prefs[p2][it],2) for it in si])

    # Sum up the products
    pSum = sum([prefs[p1][it]*prefs[p2][it] for it in si])

    # Calculate Person score
    num = pSum - (sum1*sum2/n)
    den = sqrt((sum1Sq - pow(sum1,2)/n)*(sum2Sq - pow(sum2,2)/n))
    if den == 0: return 0

    r = num/den
    return r

# Returns the best matches for person from the prefs dictionary.
# Number of results and similarity function are optional params.
def topMatch(prefs, person, n=5, similarity=sim_person):
    scores = [(similarity(prefs, person, other), other) 
              for other in prefs if other!=person]

    # Sort the list so the highest scores appear at the top
    scores.sort()
    scores.reverse()
    return scores[0:n]

# Gets recommendations for a person by using a weighted average
# of every other user's rankings 
def getRecommendations(prefs, person, similarity=sim_person):
    totals = {}
    simSums = {}
    for other in prefs:
        # don't compare me to myself
        if other == person: continue
        sim = similarity(prefs, person, other)

        # ignore scores of zero of lower
        if sim<=0: continue
        for item in prefs[other]:

            # only score movies I haven't seen yet
            if item not in prefs[person] or prefs[person][item]==0:
                # Similarity * Score
                totals.setdefault(item, 0)
                totals[item]+=prefs[other][item]*sim
                # Sum of similarities
                simSums.setdefault(item, 0)
                simSums[item]+=sim

    # Create the normalized list 
    rankings = [(total/simSums[item], item) for item, total in totals.items()]

    # Return the sorted list 
    rankings.sort()
    rankings.reverse()
    return rankings
5
  • 4
    Please make sure the indentation is appropriate in any code you post, especially Python code, since the indentation affects the behaviour of Python.
    – khelwood
    Commented Feb 15, 2016 at 11:01
  • 59
    I think you downvoters are a little bit rough on the newbies.
    – bgusach
    Commented Feb 15, 2016 at 11:07
  • 1
    @bgusach: My guess is that the downvotes are due to lack of research, since dict.items is pretty easy to find in the docs. OTOH, I suppose the official Python docs can be a bit intimidating if Python is your first programming language, since they are aimed at seasoned programmers.
    – PM 2Ring
    Commented Feb 15, 2016 at 11:18
  • 6
    @PM2Ring, searching and reading docs is the daily bread of any programmer, but either long time ago or not so long, all of us were that n00b asking the obvious, wihout a clue on where to start. Sometimes people forget that SO is a Q&A site, not a strictly professional Q&A site.
    – bgusach
    Commented Feb 15, 2016 at 12:12
  • Related: stackoverflow.com/questions/30418481/… Commented Jun 28, 2019 at 12:56

3 Answers 3

67

Try without dot notation like this:

sample_dict = {'name': 'John', 'age': 29}
print(sample_dict['name']) # John
print(sample_dict['age'])  # 29
2
  • 8
    Explanation for Python newbies?
    – joe
    Commented Sep 12, 2021 at 0:44
  • 9
    @joe because that how class inheritence works in python, you are doing 'Dict.thing' which is trying to look up a method for Dict, it's not how JS works when you add a key it becomes a lookup table, Commented Feb 3, 2022 at 0:33
51

The dict.items iterates over the key-value pairs of a dictionary. Therefore for key, value in dictionary.items() will loop over each pair. This is documented information and you can check it out in the official web page, or even easier, open a python console and type help(dict.items). And now, just as an example:

>>> d = {'hello': 34, 'world': 2999}
>>> for key, value in d.items():
...   print key, value
...
world 2999
hello 34

The AttributeError is an exception thrown when an object does not have the attribute you tried to access. The class dict does not have any predictors attribute (now you know where to check it :) ), and therefore it complains when you try to access it. As easy as that.

1
  • 2
    Thank so much for pointing the way. I had didn't realize that totals.items refers to dict.items and thought it was like a JSON object of sorts. Now I know how to approach such issues in future. Thanks again.
    – Mike
    Commented Feb 16, 2016 at 2:52
17
product_details = {
  'name':'mobile',
  'company':'samsung'
}

Accessing product_details.name will throw the error dict object has no attribute 'name'.

The reason is because we are using dot (.) to access dict item. The right way is like this:

product_details['name']

We use dot operator to access values from objects in python.

dictionary.items() allows us to loop through key:value pairs in the dictionary

for key, value in product_details.items(): 
    print(key,':',value)

for each iteration of the loop a key and its value is assigned to the variables key and value here. This is how items() method works.

Not the answer you're looking for? Browse other questions tagged or ask your own question.