迭代和索引

2024-09-28 23:15:59 发布

您现在位置:Python中文网/ 问答频道 /正文

我现在被困在这个程序。我试图通过分子方程来确定化合物的分子量(只有Cs,Hs,Os)。我也不确定如何正确格式化[index+1],因为我正试图确定“x”后面的下一个字符是什么,看它是一个数字还是另一个分子

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 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

这就是我一直得到的错误

^{pr2}$

Tags: orin程序forindexif分子else
3条回答

以下是我对如何解决这个问题的看法。基本上,你可以跟踪当前的“状态”并对每个字符进行一次精确的迭代,这样你就不会忘记你在哪里或者类似的东西。在

def getWeightFromChemical(chemical):
    chemicals = {"C" : 6, "H" : 1, "O" : 8}
    return chemicals.get(chemical, 0)

def chemicalWeight(chemicalFormula):
    lastchemical = ""
    currentnumber = ""
    weight = 0

    for c in chemicalFormula:
        if str.isalpha(c): # prepare new chemical
            if len(lastchemical) > 0:
                weight += getWeightFromChemical(lastchemical)*int("1" if currentnumber == "" else currentnumber)
            lastchemical = c
            currentnumber = ""
        elif str.isdigit(c): # build up number for previous chemical
            currentnumber += c

    # one last check
    if len(lastchemical) > 0:
        weight += getWeightFromChemical(lastchemical)*int("1" if currentnumber == "" else currentnumber)

    return weight

顺便说一句,有人知道如何重构这个代码段,使之不再有两次吗?我很讨厌。在

这里提供的答案集中在解决问题的两个不同方面:

  1. 一个非常具体的错误解决方案(int is not iterable),通过纠正一些代码。在
  2. 对如何处理代码有一个更大的视角。在

关于1,您的问题的一个注释指出了这个问题:内部循环中元组解包的语法。 元组解包的一个例子是

a,b = ['a','b']

在这里,Python将获取右手边(RHS)的第一个元素,并将其分配给左手边的第一个名称(LHS),即RHS的第二个元素,并将其分配给LHF中的第二个名称。在

你的内环出了问题, for index, y in range(index + 1, 1000000000), 相当于试着去做

^{pr2}$

现在,整数不是元素的集合,所以这行不通。在

关于2,您应该关注模块化的策略,这基本上意味着您为每个子问题编写一个函数。Python几乎就是为此而生的。(注意,这种策略并不一定意味着为每个子问题编写Python模块。)

在您的情况下,您的主要目标可以分为几个子问题:

  1. 得到分子序列。在
  2. 把序列分成单独的序列。在
  3. 把序列分成H,C和O元素。在
  4. 给定氢、碳和氧原子的数目,计算分子量。在

第3步和第4步是独立函数的最佳候选,因为它们的核心问题与其余的上下文无关。在

在这里,我假设我们一次只能得到一个序列,并且它们的形式可以是:

  • CH4
  • CHHHH
  • CP4H3OH

第三步:

def GetAtoms(sequence):
  ''' 
  Counts the number of C's, H's and O's in sequence and returns a dictionary.
  Only works with a numeric suffices up to 9, e.g. C10H12 would not work.
  '''
  atoms = ['C','H','O']  # list of which atoms we want to count.
  res = {atom:0 for atom in atoms}
  last_c = None
  for c in sequence:
    if c in atoms:
      res[c] += 1
      last_c = c
    elif c.isdigit() and last_c is not None:
      res[last_c] += int(c) - 1
      last_c = None
    else:
      last_c = None
   return res

你可以看到,不管你如何获得序列和如何计算分子量,这个方法都是有效的(前提条件下)。如果以后需要扩展如何获得原子计数的功能,可以在不影响其余逻辑的情况下进行更改。在

第四步:

def MolecularWeight(atoms):
  return atoms['H']*1 + atoms['C']*8 + atoms['O']*18

现在你的逻辑是:

while True:
  chemicalFormula = input("Enter the chemical formula, or enter key to quit: ")
  if len(chemicalFormula) == 0:
    break

  print 'Molecular weight of', chemicalFormula, 'is', MolecularWeight(GetAtoms(chemicalFormula))

你应该改变这条线

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

^{pr2}$

相关问题 更多 >