3

I have a python code that contains a list dict, where each element is a list of arbitrary size. I am looping over the elements as follows:

for i in range(len(dict)):
    for j in range(1,len(dict[i])):
        str = dict[i][j]

at this point, I get an error saying IndexError: list index out of range. I am using range(1,len(dict)) because I want to skip the first element of each list in dict. At the point the error is generated, i=5, len(dict[5])=2, so j should be looping over only 1, but when I check the j value, I get 2. How is this possible?

What's even weirder is that when I type the above code in the python console, I get no such error and everything works fine.

Edit: the full code is: (note the change from dict to keywords)

import re

conds = [['emerald cryo i&ii,a,01', '40% (v/v) mpd', 'sodium phosphate dibasic', 'citric acid'],['emerald cryo i&ii,a,02', '40% (v/v) ethylene glycol', 'sodium acetate', 'acetic acid'],['emerald cryo i&ii,a,03', '50% (v/v) peg-200', 'citrate', 'na']]

keywords = [["'sodium acetate'", " 'sodium acetate'", " 'na(ac)'", " 'na acetate'", " 'na_acetate'"],["'rbcl+mgcl2'", " 'rbcl+mgcl2 (0.025m each)'"]]

#cycle through elements to see if there is a match to the dictionary
for i in range(len(keywords)):
    for j in range(1,len(keywords[i])):
        print j
        for k in range(len(conds)):
            str = keywords[i][j].strip().strip("'").strip() #this is where the error occurs
            match = [(str == l) for l in conds[k]]
            ind = [i for i, x in enumerate(match) if x]
            if len(ind) !=0:
                print ind
                print str

The actual conds and keywords lists are lot longer and being read in from a file, but I just copied and pasted two elements each from the python console.

Edit 2: printed out i, j, len(dict[i]), dict[i] in the inner loop. The output is too long to put here, but here is a condensed version:

0 1 3 ["'potassium acetate'", " 'k(oac)'", " 'potassium acetate'"]
3 1 3 ["'ammonium nitrate'", " '(nh4)2(no)3'", " 'ammonium nitrate'"]
3 1 3 ["'ammonium nitrate'", " '(nh4)2(no)3'", " 'ammonium nitrate'"]
3 1 3 ["'ammonium nitrate'", " '(nh4)2(no)3'", " 'ammonium nitrate'"]
4 1 5 ["'sodium acetate'", " 'sodium acetate'", " 'na(ac)'", " 'na acetate'", " 'na_acetate'"]
4 1 5 ["'sodium acetate'", " 'sodium acetate'", " 'na(ac)'", " 'na acetate'", " 'na_acetate'"]
5 1 2 ["'rbcl+mgcl2'", " 'rbcl+mgcl2 (0.025m each)'"]
4 1 5 ["'sodium acetate'", " 'sodium acetate'", " 'na(ac)'", " 'na acetate'", " 'na_acetate'"]
4 1 5 ["'sodium acetate'", " 'sodium acetate'", " 'na(ac)'", " 'na acetate'", " 'na_acetate'"]
3 1 3 ["'ammonium nitrate'", " '(nh4)2(no)3'", " 'ammonium nitrate'"]
3 1 3 ["'ammonium nitrate'", " '(nh4)2(no)3'", " 'ammonium nitrate'"]
4 1 5 ["'sodium acetate'", " 'sodium acetate'", " 'na(ac)'", " 'na acetate'", " 'na_acetate'"]
[2]
sodium acetate
4 1 5 ["'sodium acetate'", " 'sodium acetate'", " 'na(ac)'", " 'na acetate'", " 'na_acetate'"]
4 1 5 ["'sodium acetate'", " 'sodium acetate'", " 'na(ac)'", " 'na     acetate'", " 'na_acetate'"]
5 1 2 ["'rbcl+mgcl2'", " 'rbcl+mgcl2 (0.025m each)'"]

...

5 2 2 ["'rbcl+mgcl2'", " 'rbcl+mgcl2 (0.025m each)'"]
Traceback (most recent call last):
  File "<stdin>", line 1, in <module>
  File "coarseCondEdit.py", line 38, in <module>
    str = keywords[i][j].strip().strip("'").strip()
IndexError: list index out of range
17
  • 2
    list named dict. Why? Commented May 6, 2015 at 16:25
  • 2
    ...why is dict a list? This is confusing. Show your dict contents perhaps. Commented May 6, 2015 at 16:26
  • 1
    @AlexeyGorozhanov no, dict is not a keyword. List if keywords can be found here Commented May 6, 2015 at 16:29
  • 4
    It's an interesting problem, but I don't think I can investigate any farther without an MCVE. Commented May 6, 2015 at 16:32
  • 3
    Meanwhile, dict isn't a reserved word that can't be used as a variable name, and neither is str, but using them is still a bad idea, behind that hides the names of the types. If you later want to write s = str(i) or d = dict(*pairs), you're going to get a confusing error because you're trying to call your string object or list object instead of the str or dict constructors. And, of course, you're confusing everyone who reads your code, and making them have to think twice as hard to follow it, which is a bad idea when you want people to find a problem for you. Commented May 6, 2015 at 16:35

1 Answer 1

5

The line

ind = [i for i, x in enumerate(match) if x]

changes your i that you use for the outer loop.

That btw wouldn't have happened if you used normal Python looping instead of indexed looping:

for words in keywords:
    for word in words[1:]:
        for cond in conds:
            word = word.strip().strip("'").strip()
            match = [(word == l) for l in cond]
            ind = [i for i, x in enumerate(match) if x]
            if len(ind) !=0:
                print ind
                print word

Doesn't that also look much nicer and more meaningful?

The variable names could be further improved, but I'll leave that up to you as I don't know proper names for your things.

Sign up to request clarification or add additional context in comments.

2 Comments

I can't believe I overlooked that. Thanks!
@sodiumnitrate Also note the code and text that I just added to my answer.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.