For 2023 (and 2024 ...) - we are now fully retired from IT training. We have made many, many friends over 25 years of teaching about Python, Tcl, Perl, PHP, Lua, Java, C and C++ - and MySQL, Linux and Solaris/SunOS too. Our training notes are now very much out of date, but due to upward compatability most of our examples remain operational and even relevant ad you are welcome to make us if them "as seen" and at your own risk.
Lisa and I (Graham) now live in what was our training centre in Melksham - happy to meet with former delegates here - but do check ahead before coming round. We are far from inactive - rather, enjoying the times that we are retired but still healthy enough in mind and body to be active!
I am also active in many other area and still look after a lot of web sites - you can find an index ((here)) |
Python key error
Posted by PaulStat (PaulStat), 6 October 2010 Ok so I have the following code, ReadMyData passes a tuple of dictionaries to InsertChannelPrograms, which then builds a values tuple and appends it to a list depending on how big the input tuple (listDict) was. Code:def ReadMyData(self,datFile): channelID = datFile[:-4] fields = ["PROGTITLE", "SUBTITLE", "EPISODE", "YEAR", "DIRECTOR", "PERFORMERS","PREMIERE", "FILM", "REPEAT", "SUBTITLES", "WIDESCREEN", "NEWSERIES","DEAFSIGNED", "BNW", "STARRATING", "CERTIFICATE", "GENRE", "DESCRIPTION","CHOICE", "DATE", "STARTTIME", "ENDTIME", "DURATION"] delim = '~' lineReader = csv.DictReader(open("./input/" + datFile,'rb'), delimiter=delim,fieldnames=fields) # Read the header lines lineReader.next() lineReader.next() channelPrograms = [] for row in lineReader: channelPrograms.append(row) for i in range(len(channelPrograms)): if (i+3) < len(channelPrograms): self.InsertChannelProgrammes(channelID,(channelPrograms[i], channelPrograms[i+1],channelPrograms[i+2],channelPrograms[i+3])) elif (i+2) < len(channelPrograms): self.InsertChannelProgrammes(channelID,(channelPrograms[i], channelPrograms[i+1],channelPrograms[i+2])) elif (i+1) < len(channelPrograms): self.InsertChannelProgrammes(channelID,(channelPrograms[i], channelPrograms[i+1])) else: self.InsertChannelProgrammes(channelID,(channelPrograms[i]))
def InsertChannelProgrammes(self,channelID,listDict): sqlString = """INSERT INTO CHANNELPROGRAMME(CHANNELID,DTE,STARTTIME) VALUES(%s,%s,%s)""" columns = [] for i in range(len(listDict)): tempDict = listDict[i] valuesTuple = (channelID,self.FormatDate(tempDict["DATE"]),tempDict["STARTTIME"]) columns.append(valuesTuple) if len(columns) > 0: self._cursor.executemany(sqlString,columns)
|
|
This code gives me the error Quote:Traceback (most recent call last): File "noThread.py", line 82, in <module> processing.ReadMyData(channelFile+'.dat') File "noThread.py", line 52, in ReadMyData self.InsertChannelProgrammes(channelID,(channelPrograms[i])) File "noThread.py", line 58, in InsertChannelProgrammes tempDict = listDict[i] KeyError: 0 |
|
I simplified the concept to see if it would work and it does, see below: Code:>>> dateList = [] >>> >>> dateDict1 = {'DATE': '2010-06-20'} >>> dateDict2 = {'DATE': '2010-06-28'} >>> >>> dateList.append(dateDict1) >>> dateList.append(dateDict2) >>> >>> def PassList(): ... TakeList((dateList[0],dateList[1])) ... >>> def TakeList(listDict): ... for i in range(len(listDict)): ... tempDict = listDict[i] ... print tempDict["DATE"] ... >>> PassList() 2010-06-20 2010-06-28 |
|
So any ideas why I'm getting this? Posted by dcorking (David Corking), 25 February 2011 Paul, You should be able to get more detail with the debugger. Meanwhile, my guess is that the KeyError happens because (at the time of the traceback) listDict is not a list of dictionaries but a dictionary. Take a look at this line Code:self.InsertChannelProgrammes(channelID,(channelPrograms[i])) |
|
I made a quick demo program to illustrate my idea Code:#!/usr/bin/python
myDictCoats = { "tree" : "bark" , "dog" : "fur" } myDictFrench = { "boy": "garcon", "fish": "poisson"}
myTupleOfDicts = (myDictCoats, myDictFrench)
i=0
print "This is when your program seems to work: two appended dictionaries" # compare the next line to self.InsertChannelProgrammes(channelID,(channelPrograms[i], channelPrograms[i+1])) good = (myTupleOfDicts [i], myTupleOfDicts [i+1]) print good print ("This object has"), type(good), (" and length"), len(good) print "Zeroth element is", good [i] print
print "I suggest that this is the failure point: one dictionary" # compare the next line to self.InsertChannelProgrammes(channelID,(channelPrograms[i])) broken = (myTupleOfDicts [i]) print broken print "This object has", type(broken), (" and length"), len(broken), "\n" # As this is of type 'dictionary', not a tuple, print broken [i] will give KeyError: i
# A quick fix might be easy: add a comma print "I added a comma to the assignment statement" fixed = (myTupleOfDicts [i],) print fixed print ("This object has"), type(fixed), (" and length"), len(fixed) print "Zeroth element is", fixed [i] |
|
Sorry about all the repetition. Run my demo with the debugger or the interpreter to play with it. My output is Quote:This is when your program seems to work: two appended dictionaries ({'tree': 'bark', 'dog': 'fur'}, {'boy': 'garcon', 'fish': 'poisson'}) This object has <type 'tuple'> and length 2 Zeroth element is {'tree': 'bark', 'dog': 'fur'}
I suggest that this is the failure point: one dictionary {'tree': 'bark', 'dog': 'fur'} This object has <type 'dict'> and length 2
I added a comma to the assignment statement ({'tree': 'bark', 'dog': 'fur'},) This object has <type 'tuple'> and length 1 Zeroth element is {'tree': 'bark', 'dog': 'fur'} |
|
I think you might be able to fix your code if you add a comma near the end of line 52 If that doesn't help, you could try Graham's new forum, http://www.wellho.net/ask/
This page is a thread posted to the opentalk forum
at www.opentalk.org.uk and
archived here for reference. To jump to the archive index please
follow this link.
|
|