我有这本字典,其中的键代表原子类型,值代表原子质量:
mass = {'H': 1.007825, 'C': 12.01, 'O': 15.9994, 'N': 14.0067, 'S': 31.972071,
'P': 30.973762}
我要做的是创建一个给定分子的函数,例如('H2-N-C6-H4-C-O-2H')
,在mass
字典上进行迭代并计算给定分子的原子质量。质量值必须乘以原子类型之后的数字:H2 = H.value * 2
我知道,首先我必须隔离给定分子的键,为此我可以使用string.split('-')
。然后,我想如果给定分子的键在词典中,我可以使用和if
块来确定要完成的条件。但是后来我迷失了如何继续查找字典中每个键的质量。
预期结果应该类似于:
mass_counter('H2-N15-P3')
out[0] 39351.14
我该怎么办?
编辑:
这是我到目前为止尝试过的
# Atomic masses
mass = {'H': 1.007825, 'C': 12.01, 'O': 15.9994, 'N': 14.0067, 'S': 31.972071,
'P': 30.973762}
def calculate_atomic_mass(molecule):
"""
Calculate the atomic mass of a given molecule
"""
mass = 0.0
mol = molecule.split('-')
for key in mass:
if key in mol:
atom = key
return mass
print calculate_atomic_mass('H2-O')
print calculate_atomic_mass('H2-S-O4')
print calculate_atomic_mass('C2-H5-O-H')
print calculate_atomic_mass('H2-N-C6-H4-C-O-2H')
答案 0 :(得分:5)
鉴于所有组件的形状均为user product
u_1 p_1
u_1 p_2
u_1 p_3
u_2 p_1
u_2 p_2
u_2 p_3
,在这里用正则表达式标识零件可能会更容易,例如:
select a.user, b.product from (select user from users group by user) a
(select product from products group by product) b;
这里我们的regular expression [wiki]捕获了Aa123
个序列和一个数字序列(可能是空的)import re
srch = re.compile(r'([A-Za-z]+)(\d*)')
mass = {'H': 1.007825, 'C': 12.01, 'O': 15.9994, 'N': 14.0067, 'S': 31.972071, 'P': 30.973762}
def calculate_atomic_mass(molecule):
return sum(mass[a[1]]*int(a[2] or '1') for a in srch.finditer(molecule))
,它们分别是第一个捕获组和第二个捕获组,并且因此可以与[A-Z-a-z]
和\d*
进行匹配。
然后产生:
a[1]
因此,我们将第一个捕获组的a[2]
(原子的名称)乘以末尾的数字之和,并使用>>> print(calculate_atomic_mass('H2-O'))
18.01505
>>> print(calculate_atomic_mass('H2-S-O4'))
97.985321
>>> print(calculate_atomic_mass('C2-H5-O-H'))
46.06635
>>> print(calculate_atomic_mass('H2-N-C6-H4-C-O-2H'))
121.130875
>>> print(calculate_atomic_mass('H2-N15-P3'))
305.037436
,以防找不到这样的数字
或者我们可以先拆分数据,然后查找原子部分和数字部分:
mass[..]
答案 1 :(得分:2)
以下是不使用正则表达式的答案:
import string
# Atomic masses
masses = {'H': 1.007825, 'C': 12.01, 'O': 15.9994, 'N': 14.0067, 'S': 31.972071,
'P': 30.973762}
def calculate_atomic_mass(molecule):
"""
Calculate the atomic mass of a given molecule
"""
mass = 0.0
for key in molecule.split('-'):
# check if any number is available
if not key[-1] in string.digits:
el, n = key, 1
# check length of element label (1 or 2)
elif key[1] in string.digits:
el, n = key[:1], int(key[1:])
else:
el, n = key[:2], int(key[2:])
mass += masses[el]*n
return mass
print calculate_atomic_mass('H2-O')
print calculate_atomic_mass('H2-S-O4')
print calculate_atomic_mass('C2-H5-O-H')
print calculate_atomic_mass('H2-N-C6-H4-C-O-H2')
答案 2 :(得分:2)
这就是我要做的。您实际上不需要遍历字典。相反,您需要遍历分子中的原子,然后在字典中查找(随机地)事物。
在此举一个例子,该例子假设组成该分子的任何种类的原子绝不会超过10个,并且每个元素的名称只有一个字母长。
# Atomic masses.
MASSES = {'H': 1.007825, 'C': 12.01, 'O': 15.9994, 'N': 14.0067, 'S': 31.972071,
'P': 30.973762}
def calculate_atomic_mass(molecule):
""" Calculate the atomic mass of a given molecule. """
mass = 0.0
for atom in molecule.split('-'):
if len(atom) == 1:
mass += MASSES[atom]
else:
atom, count = atom[0], atom[1]
mass += MASSES[atom] * int(count)
return mass
print calculate_atomic_mass('H2-O') # -> 18.01505
print calculate_atomic_mass('H2-S-O4') # -> 97.985321
print calculate_atomic_mass('C2-H5-O-H') # -> 46.06635
print calculate_atomic_mass('H2-N-C6-H4-C-O-H2') # -> 122.1387