【问题标题】:How do I detect the correct variables from strings in python如何从python中的字符串中检测正确的变量
【发布时间】:2020-12-10 14:10:11
【问题描述】:

我正在尝试构建一个程序,该程序采用相当简单的化学公式并对其进行平衡。

假设一个例子是 Ca(Oh)₂ + HNO₃ → Ca(NO₃)₂ + H₂O

据我所知,没有办法在 python 中处理下标,所以我决定采用这种格式 Ca(Oh)_2 + HNO_3 = Ca(NO_3)_2 + H_2O,将箭头替换为=,然后下划线作为下标。

到目前为止,我已经设法将等式的第一部分和第二部分分成单独的元素。 所以我有清单

starters = ['Ca(Oh)_2', 'HNO_3']
products = ['Ca(NO_3)_2', 'H_2O']

这就是我卡住的地方。

如何遍历元素,并获取每个元素的数量。

我想把它存储在一个类似于

的字典中
starter_amount = {element name; amount}
product_amount = {element name; amount}

理想情况下,它也会理解例如 2NO_3,意味着有 2N 和 6 O

【问题讨论】:

标签: python string variables


【解决方案1】:

这是一个相当复杂的问题,解决随机公式只是第一步。我希望以下功能对您有所帮助。它会解析您的随机公式以提取所有原子(顺便说一句:您应该在 Ca(OH)_2 中将 H 大写。否则,它会将 Oh 视为一个元素。)。

使用此函数,您可以获得该产品或析出物中所有原子的列表。

def expand(stoch):
    f = ''
    for c in stoch:
        if c.isupper() or c == "(":
            f+=' '+c
        else:
            f+=c
    while '_' in f:
        i = f.rfind("_")
        if f[i-1]==")":
            l = 1
            start = i-2
            while l > 0:
                if f[start]=="(":
                    l-=1
                elif f[start]==")":
                    l+=1
                start-=1
            subform = f[start+2:i-1]
            subform = expand(subform)
            k = i+1
            while k<len(f):
                k+=1
                if not f[i+1:k].isdigit():break
            
            num = f[i+1:k]
            f = f[:start+1]+(subform+' ')*int(num)+f[k:]
            
        else:
            nc = 1
            subform = f[i-nc]
            while subform.islower():
                nc+=1
                subform = f[i-nc:i]

            k = i+1
            while k<len(f):
                k+=1
                if not f[i+1:k].isdigit():break
            
            num = f[i+1:k]
            f = f[:i-nc]+(subform+' ')*int(num)+f[k:]
    while '  ' in f: f = f.replace('  ',' ')  
    return f

该函数采用随机公式的语法,分解它并通过将每个元素乘以它应该的次数来简化 if。 结果是:

print(expand("Ca(OH)_2"))
print(expand("C_6H_12(OH)_2"))

## Ca O H O H 
## C C C C C C H H H H H H H H H H H H O H O H 

由于它是递归的,它能够解析嵌套的括号:

print(expand("Ca_3(C_3H_5(OH)_3)_2"))

## Ca Ca Ca C C C H H H H H O H O H O H C C C H H H H H O H O H O H 

如果您将其应用于您的问题,我建议创建一个区分 Product 和 Educt 并列出组件及其原子内容的字典,以便您稍后可以使用迭代程序访问它:

starters = ['Ca(OH)_2', 'HNO_3']
products = ['Ca(NO_3)_2', 'H_2O']

formula = {'Educts':[],'Products':[]}
for e in starters:
    atoms = expand(e).split(' ')
    while '' in atoms: atoms.remove('')
    formula['Educts'].append({'Formula':e,'Atoms':sorted(atoms)})
for p in products:
    atoms = expand(p).split(' ')
    while '' in atoms: atoms.remove('')
    formula['Products'].append({'Formula':p,'Atoms':sorted(atoms)})

for k,v in formula.items():
    print(k)
    for e in v:
        for k2,v2 in e.items():
            print('  - '+k2+': '+str(v2))
        print('')
 
## Output:
##
##Educts
##  - Formula: Ca(OH)_2
##  - Atoms: ['Ca', 'H', 'H', 'O', 'O']
##
##  - Formula: HNO_3
##  - Atoms: ['H', 'N', 'O', 'O', 'O']
##
##Products
##  - Formula: Ca(NO_3)_2
##  - Atoms: ['Ca', 'N', 'N', 'O', 'O', 'O', 'O', 'O', 'O']
##
##  - Formula: H_2O
##  - Atoms: ['H', 'H', 'O']

或者只是这个字典:{'Educts': [{'Formula': 'Ca(OH)_2', 'Atoms': ['Ca', 'O', 'H', 'O', 'H']}, {'Formula': 'HNO_3', 'Atoms': ['H', 'N', 'O', 'O', 'O']}], 'Products': [{'Formula': 'Ca(NO_3)_2', 'Atoms': ['Ca', 'N', 'O', 'O', 'O', 'N', 'O', 'O', 'O']}, {'Formula': 'H_2O', 'Atoms': ['H', 'H', 'O']}]}

【讨论】:

  • 好的,我在这个练习中获得了太多乐趣,并且还编写了程序的其余部分。它采用化学式(没有数量)并解决化学计量问题。见这里:github.com/Tarlanc/Side_Projects(脚本:chemical_Parser.py)
猜你喜欢
  • 2021-07-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-12-05
  • 1970-01-01
  • 2014-03-03
  • 2017-10-13
  • 2018-11-14
相关资源
最近更新 更多