python - 如何从python中的字符串中检测正确的变量
问题描述
我正在尝试构建一个程序,该程序采用相当简单的化学公式并对其进行平衡。
假设一个例子是 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
解决方案
这是一个相当复杂的问题,解决随机公式只是第一步。我希望以下功能对您有所帮助。它会解析您的随机公式以提取所有原子(顺便说一句:您应该在 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']}]}
推荐阅读
- python - How to decode u'\xc3\xa9cosyst\xc3\xa8mes' to utf-8
- python - How can I get a PDF data from firebase storage - Python?
- python - How to print "yes" when written "y" in "Are you sure for exit" question?
- java - 无法反序列化具有最终字段的最简单对象 bu Jackson
- c# - 绑定列表框的“SelectedItems”
- sass - 使用@mixin 来“干燥”@keyframes 是个好主意吗?
- android - android pie上的Retrofit2响应为空
- socket.io - Where do I handle feathersjs/socketio-client connection error
- azure - 调整 Azure Kubernetes 服务 (AKS) 群集
- javascript - Fixed Header is wrongly positioned