add-semi-colons
add-semi-colons

Reputation: 18810

Append to python dictionary

I have a csv file that has numbers integers and floats,

"5",7.30124705657363,2,12,7.45176205440562
"18",6.83169608190656,5,11,7.18118108407457
"20",6.40446470770985,4,10,6.70549470337383
"3",5.37498781178147,17,9,5.9902122724706
"10",5.12954203598201,8,8,5.58108702947798
"9",3.93496153596789,7,7,4.35751055597501

I am doing some arithmetic and then I am trying to add them into a dictionary but I am getting key error. Here is the code that I have,

global oldPriceCompRankDict
oldPriceCompRankDict = {}

def increaseQuantityByOne(self, fileLocation):
    rows = csv.reader(open(fileLocation))
    rows.next()
    print "PricePercentage\t" + "OldQuantity\t" + "newQuantity\t" + "oldCompScore\t" + "newCompScore"
    for row in rows:
        newQuantity = float(row[2]) + 1.0
        newCompetitiveScore = float(row[1]) + float(math.log(float(newQuantity), 100))
        print row[1] + "\t", str(row[2])+"\t", str(newQuantity) + "\t", str(row[4]) + "\t", newCompetitiveScore
        oldPriceCompRankDict[row[3]].append(row[4])

I have un-ordered key, and I didn't think the key has to be in an ordered format. I thought anything could be key.

Upvotes: 1

Views: 564

Answers (2)

Alexander Nyrkov
Alexander Nyrkov

Reputation: 445

A Python dictionary type does not have an append() method. What you are doing is basically trying to call an append() method of the dictionary element accessible by key row[3]. You get a KeyError because you have nothing under key row[3].

You should substitute your code

oldPriceCompRankDict[row[3]].append(row[4])

for this:

oldPriceCompRankDict[row[3]] = row[4]

In addition, the global keyword is used inside functions to indicate that variable is a global one, you can read about it here: Using global variables in a function other than the one that created them so the right way to declare a global dictionary would be just oldPriceCompRankDict = {}

Your function will start adding to the dictionary from the second row because you call rows.next() if it is a desirable behavior then it's OK, otherwise you don't need to call that method.

Hope this was helpful, happy coding!

Upvotes: 2

Martijn Pieters
Martijn Pieters

Reputation: 1121714

No need to put in the global keyword, it's a no-op. Use a defaultdict instead:

from collections import defaultdict

oldPriceCompRankDict = defaultdict(list)

What is happening is that you never define any keys for oldPriceCompRankDict, you just expect them to be lists by default. The defaultdict type gives you a dict that does just that; when a key is not yet found in oldPriceCompRankDict a new list() instance will be used as the starting value instead of raising a KeyError.

Upvotes: 4

Related Questions