7
votes

Casser la chaîne dans les éléments de liste basés sur des mots-clés

J'essaie de créer une fonction (en python) qui prend son entrée (une formule chimique) et se divise dans une liste. Par exemple, si l'entrée était "HC2H3O2", elle l'allumerait:

def split_molecule(inputted_molecule):
    """Take the input and split it into a list
    eg: C02 => ['C', 1, 'O', 2]
    """
    # step 1: convert inputted_molecule to a list
    # step 2a: if there are two periodic elements next to each other, insert a '1'
    # step 2b: if the last element is an element, append a '1'
    # step 3: convert all numbers in list to ints

    # step 1:
    # problem: it splits Na into 'N', 'a'
    # it needs to split by periodic elements
    molecule_list = list(inputted_molecule)

    # because at most, the list can double when "1" is inserted
    max_length_of_molecule_list = 2*len(molecule_list)
    # step 2a:
    for i in range(0, max_length_of_molecule_list):
        try:
            if (molecule_list[i] in elements) and (molecule_list[i+1] in elements):
                molecule_list.insert(i+1, "1")
        except IndexError:
            break
    # step2b:     
    if (molecule_list[-1] in elements):
        molecule_list.append("1")

    # step 3:
    for i in range(0, len(molecule_list)):
        if molecule_list[i].isdigit():
            molecule_list[i] = int(molecule_list[i])

    return molecule_list


0 commentaires

3 Réponses :


5
votes

Que diriez-vous de xxx

résultat xxx

regex expliqué: xxx

Cette expression est jolie car elle accepte des "éléments" arbitraires, comme "xy". Vous pouvez l'améliorer en remplaçant le [AZ] [AZ] [AZ]? Pièce avec la liste réelle des noms des éléments, séparés par | , comme BA | NA | Mn ... | C | O

Bien sûr, les expressions régulières ne peuvent gérer que des formules très simples, analyser quelque chose comme xxx

Vous allez avoir besoin d'un vrai parseur, par exemple PyparSing (assurez-vous de vérifier "formules chimiques" sous "Exemples"). Bonne chance!


2 commentaires

C'est brillant, merci! Voulez-vous expliquer la regex?


+1 pour mentionner que vous auriez besoin d'un réel analyseur, au lieu d'un analyseur de regex



2
votes

Une expression comme celle-ci correspondra à toutes les parties d'intérêt: xxx

Vous pouvez l'utiliser avec re.findall , puis ajouter le quantificateur pour les atomes qui n'ont aucune .

ou vous pouvez utiliser une regex pour cela aussi: xxx

sortie: xxx

Le sous ajoute un 1 après tous les atomes non suivis d'un numéro.


0 commentaires

1
votes

L'approche non-regex, qui est un peu pirate pirate et probablement pas le meilleur, mais cela fonctionne:

import string

formula = 'HC2H3O2Na'
m_list = list()
for x in formula:
   if x in string.lowercase:
      m_list.append(formula[formula.index(x)-1]+x)
      _ = m_list.pop(len(m_list)-2)
   else:
      m_list.append(x)
print m_list
['H', 'C', '2', 'H', '3', 'O', '2', 'Na']


0 commentaires