索引错误:列表索引超出范围

时间:2013-05-24 03:39:15

标签: python indexing

这是我第一次在stackoverflow中发帖,所以我希望我在网站礼仪方面做得很好。我是一个初级编程类(Python),我目前的任务是根据用户输入计算碳,氢和氧的化合物的分子量。它可以是从C2到C8H19O2的任何东西,依此类推。

我有我的代码,我不断收到我不熟悉的错误。基本上我要做的是让代码通过字符读取输入复合字符,确定它是否是分子。然后,它读取前一个字符右侧的字符,以确定它是否是另一个化合物的数量。如果它是一种不同的化合物,则将之前的单一化合物添加到其总计的任何分子的运行记录中。如果它是一个数字,那么它将读取右边的下一个字符,再次确定它是一个数字还是一个字符。如果它是一个数字,它将前一个字符数乘以10,然后加上下一个,依此类推,直到它到达下一个字符(C123H2将是10 * 1 + 2,然后是10 * 12 + 3,然后它会在运行的计数中添加123个碳。一旦我们的流动结果完成,那么该数字乘以其中一个的分子量。我一直得到索引错误,说我的列表索引超出范围。非常感谢任何帮助!

def main():

C1 = 0
H1 = 0
O1 = 0
num = 0

chemicalFormula = (input("Enter the chemical formula, or enter key to quit: "))
while True:
    cformula = list(chemicalFormula)
    for index, x in enumerate(cformula):
        if x == 'C':
            if cformula[index + 1] == 'H' or cformula[index + 1] == 'O':
                C1 += 1
            else:
                for index, y in enumerate(range(index + 1, 1000000000)):
                    if cformula[index + 1] != 'H' or cformula[index + 1] != 'O':
                        num = int(y)
                        num = num*10 + int(cformula[index + 1])
                    else:
                        C1 += num
                        break
        elif x == 'H':
            if cformula[index + 1] == 'C' or cformula[index + 1] == 'O':
                H1 += 1
            else:
                for y in range(index + 1, 1000000000):
                    if cformula[index + 1] != 'C' or cformula[index + 1] != 'O':
                        num = int(y)
                        num = num*10 + cformula[index + 1]
                    else:
                        H1 += num
                        break
        elif x == 'O':
            if cformula[index + 1] == 'C' or cformula[index + 1] == 'H':
                O1 += 1
            else:
                for y in range(index + 1, 1000000000):
                    if cformula[index + 1] != 'C' or cformula[index + 1] != 'H':
                        num = int(y)
                        num = num*10 + cformula[index + 1]
                    else:
                        O1 += num
                        break
        else:
            break

weightC = 15.994*C1
weightH = 1.0079*H1
weightO = 12.011*O1

sumWeight = weightC + weightH + weightO
print("The molecular weight is ", sumWeight)

2 个答案:

答案 0 :(得分:0)

您有几个名为index的不同变量,它们相互隐藏。

首先,你正在迭代cformula:

for index, x in enumerate(cformula)

行。所以index总是在cformula的合理范围内。但就在那之后你做了

for index, y in enumerate(range(index + 1, 1000000000))

现在索引可以是1000000000,然后是:

if cformula[index + 1]

糟糕。 cformula甚至不接近大小为1000000002,因为它需要对此表达式进行合理评估。我相信你在这里并不需要enumerate

您所要做的就是使用cformula访问x - 主迭代中的当前元素。只要你只是阅读它(这是你真正需要的),它就没事了。

从这个问题来看,你似乎并不明白enumerate到底意味着什么 - 你正在使用它而你实际上并不需要任何特别的东西。

不要使用相同的变量来表示不同的东西!

答案 1 :(得分:0)

首先,对于初学者来说,这种方法看起来相当不错,竖起大拇指!现在,为了从标题中回答你的问题,错误来自于访问不存在的序列的元素,例如,四个元素序列的第五个元素。在你的情况下,我想这是由cformula[index + 1]触发的,其中索引可能已经是最后一个元素的索引。请注意,知道哪个输入触发了此错误也很有趣,我的猜测是“CO”或“C2H5OH”,因为两者都有一个复合字母,后面没有数字。

现在,如何绕过它?一个非常简单的方法是简单地接受字符串的其余部分(可以为空)并处理其内容。

count = ''
for d in cformula[index + 1:]:
    if d.isdigit():
        count += d
    else:
        break

此代码将cformula[index]之后的所有数字存储到下一个非数字。如果没有数字,则存储空字符串。请注意,这甚至不关心您正在查看哪个原子(C,H,O),因此对于可以移动到单独函数的代码来说,它是一个很好的示例。然后,在调用该函数后,检查数字字符串:

if count == '':
    # number of atoms is implicitly 1
    atoms = 1
else:
    # number of atoms is explicitly given
    atoms = int(count)
# TODO: discard len(count) elements from the input string

BTW:有dict类型可用于存储每个元素的原子数。同样,您可以使用它来存储每种原子类型的权重:

atom_weight = {'C': 15.994,
               'H': 1.0079,
               'O': 12.011,}

weight = atom_weight['C'] * C1 + atom_weight['H'] * H1 + atom_weight['O'] * O1

这不会使您的代码正确,但可以更容易地将其扩展到周期表的其余部分。 :)