0

我想改进我的 Python 代码。我在这里寻找逻辑帮助,以使用更少的代码获得相同的结果。

我的程序通过参数获取一串原子并“学习”它们,返回它已学习的原子列表。

我想知道是否有任何方法可以优化我的代码。

def mol_term(molecule):
    upper = "ABCDEFGHIJKLMNOPQRSTUVWXYZ"
    list_of_atoms = []

    for i in range(len(molecule) - 1): #goes all string long
        if molecule[i] in upper: 
            if not molecule[i+1] in upper:
                temp = molecule[i] + molecule[i+1]  #if atom has two letters
                i = i + 1
            else:
                temp = molecule[i]    #if not

            if not temp in list_of_atoms:
                    list_of_atoms.append(temp)  #if atom is not in the list appends to it
    if molecule[-1] in upper:
        list_of_atoms.append(molecule[-1])  #checks last letter


    return print(list_of_atoms)

非常感谢。

4

3 回答 3

1

您正在寻找一个正则表达式,它捕获一个大写字符,后跟一个可选的小写字符。

list(set(re.findall('[A-Z][a-z]?', 'CuBDa')))

但是您可能会忽略数字,即二氧化碳,这会做到这一点

re.findall('[A-Z][a-z]?[0-9]*', 'C4H10FO2P')

如果您只想忽略数字,则第一个表达式将起作用

于 2013-09-26T09:01:29.707 回答
0

我建议您查看 Python PLY 文档并查看 Andrew Dalke 的示例以获取分子解析示例。(http://www.dalkescientific.com/writings/NBN/parsing_with_ply.html

您可以使用原子符号和该原子/符号出现在分子中的时间来定义标记,例如对于 CH3COOH(乙酸)这样的分子

import lex

tokens = (
   "SYMBOL",
   "COUNT"
         )

t_SYMBOL = (
     r"C[laroudsemf]?|Os?|N[eaibdpos]?|S[icernbmg]?|P[drmtboau]?|"
     r"H[eofgas]?|A[lrsgutcm]|B[eraik]?|Dy|E[urs]|F[erm]?|G[aed]|"
     r"I[nr]?|Kr?|L[iaur]|M[gnodt]|R[buhenaf]|T[icebmalh]|"
     r"U|V|W|Xe|Yb?|Z[nr]"
        )

def t_COUNT(t):
    r"\d+"
    t.value = int(t.value)
    return t



lex.lex()

lex.input("CH3COOH")
for tok in iter(lex.token, None):
    print repr(tok.type), repr(tok.value)

当我运行代码时,我得到以下信息

'符号' 'C' '符号' 'H' '计数' 3 '符号' 'C' '符号' 'O' '符号' 'O' '符号' 'H'

更多信息在这里 http://www.dabeaz.com/ply/

于 2013-09-26T09:18:20.557 回答
0

这应该可以解决问题

import re
molecule = 'CH3COOH'
print set(re.findall('[A-Z][a-z]?',molecule))

这将打印:

set(['H', 'C', 'O'])
于 2013-09-26T09:04:24.463 回答