Как перебрать словарь и оперировать его элементами? - PullRequest
0 голосов
/ 27 октября 2018

У меня есть этот словарь, где ключи представляют атомные типы, а значения представляют атомные массы:

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 block для определения условия, которое необходимо выполнить, если ключ данной молекулы находится в словаре. Но позже я забыл о том, как мне найти массу для каждого ключа словаря.

Ожидаемый результат должен быть примерно таким:

mass_counter('H2-N15-P3')

out[0] 39351.14

Как я мог это сделать?

EDIT:

Это то, что я пробовал до сих пор

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

Ответы [ 3 ]

0 голосов
/ 27 октября 2018

Вот ответ без регулярного выражения:

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')
0 голосов
/ 27 октября 2018

Вот как бы я это сделал.Вам действительно не нужно перебирать словарь.Вместо этого вам нужно перебирать атом (ы) в молекуле и искать вещи (случайным образом) в словаре.

Вот пример такого действия, при котором предполагается, что никогда не будет более 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
0 голосов
/ 27 октября 2018

Учитывая, что все компоненты имеют форму 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))

Здесь наше регулярное выражение [wiki] таким образом захватывает последовательность [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' в случае, если такое число не может быть найдено.

Или мы можем сначала разбить данные, а затем искать атомную часть и числовую часть:

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
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...