简体   繁体   English

如何迭代字典并使用其元素进行操作?

[英]How to iterate over a dictionary and operate with its elements?

I have this dictionary, where the keys represent atom types and the values represent the atomic masses: 我有这个字典,其中键表示原子类型,值表示原子质量:

mass = {'H': 1.007825, 'C': 12.01, 'O': 15.9994, 'N': 14.0067, 'S': 31.972071,
        'P': 30.973762}

what I want to do is to create a function that given a molecule, for instance ('H2-N-C6-H4-CO-2H') , iterates over the mass dictionary and calculates the atomic mass on the given molecule. 我想要做的是创建一个给出分子的函数,例如('H2-N-C6-H4-CO-2H') ,迭代mass字典并计算给定分子上的原子质量。 The value of the mass must be multiplied by the number that comes right after the atom type: H2 = H.value * 2 质量的值必须乘以原子类型后面的数字: H2 = H.value * 2

I know that firstly I must isolate the keys of the given molecules, for this I could use string.split('-') . 我知道首先我必须隔离给定分子的键,为此我可以使用string.split('-') Then, I think I could use and if block to stablish a condition to accomplish if the key of the given molecule is in the dictionary. 然后,我认为if给定分子的键在字典中,我可以使用和if阻止建立条件来完成。 But later I'm lost about how I should proceed to find the mass for each key of the dictionary. 但后来我迷失了我应该如何继续为字典中的每个键找到质量。

The expected result should be something like: 预期结果应该是这样的:

mass_counter('H2-N15-P3')

out[0] 39351.14

How could I do this? 我怎么能这样做?

EDIT: 编辑:

This is what I've tried so far 这是我到目前为止所尝试的

# 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')

Given all components have the shape Aa123 , It might be easier here to identify parts with a regex, for example: 鉴于所有组件都具有形状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))

Here our regular expression [wiki] thus captures a sequence of [AZaz] s, and a (possibly empty) sequence of digits ( \\d* ), these are the first and second capture group respectively, and thus can be obtained for a match with a[1] and a[2] . 这里我们的正则表达式[wiki]因此捕获一系列[AZaz] s和一个(可能是空的)数字序列( \\d* ),它们分别是第一个和第二个捕获组,因此可以获得匹配用a[1]a[2]

this then yields: 然后产生:

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

We thus take the sum of the mass[..] of the first capture group (the name of the atom) times the number at the end, and we use '1' in case no such number can be found. 因此,我们将第一个捕获组的mass[..] (原子的名称)的总和乘以最后的数字,如果找不到这样的数字,我们使用'1'

Or we can first split the data, and then look for a atom part and a number part: 或者我们可以先分割数据,然后查找原子部分和数字部分:

import re
srch = re.compile(r'^([A-Za-z]+)(\d*)$')

def calculate_atomic_mass(molecule):
    """
    Calculate the atomic mass of a given molecule
    """
    result = 0.0
    mol = molecule.split('-')
    if atm in mol:
        c = srch.find(atm)
        result += result[c[1]] * int(c[2] or '1')
    return result

Here is an answer without regex: 这是一个没有正则表达式的答案:

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

Here's how I would do it. 这是我将如何做到这一点。 You don't really need to iterate over the dictionary. 你真的不需要迭代字典。 Instead you need to iterate over the atom(s) in the molecule and look things up (randomly) in the dictionary. 相反,你需要迭代分子中的原子并在字典中查找(随机)。

Here's an example of doing that which assumes that there'll never be more that 10 atoms of any kind making up the molecule and the each element's name is only one letter long. 这是一个做这样的例子,它假定组成分子的任何类型的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

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM