我在python中有一个列表,其中包含一个以Newick格式编写的树,如下所示:
['(BMNH833953:0.16529463651919140688,(((BMNH833883:0.22945757727367316336,(BMNH724182a:0.18028180766761139897,(BMNH724182b:0.21469677818346077913,BMNH724082:0.54350916483644962085):0.00654573856803835914):0.04530853441176059537):0.02416511342888815264,(((BMNH794142:0.21236619242575086042,(BMNH743008:0.13421900772403019819,BMNH724591:0.14957653992840658219):0.02592135486124686958):0.02477670174791116522,BMNH703458a:0.22983459269245612444):0.00000328449424529074,BMNH703458b:0.29776257618061197086):0.09881729077887969892):0.02257522897558370684,BMNH833928:0.21599133163597591945):0.02365043128986757739,BMNH724053:0.16069861523756587274):0.0;']
以树形式显示如下:
我正在尝试编写一些代码,这些代码将查看列表项并返回ID(BMNHxxxxxx),这些ID通过分支长度0(或者例如<0.001)连接(以红色突出显示)。我想过使用正则表达式如:
JustTree = []
with JustTree as f:
for match in re.finditer(r"(?<=Item\sA)(?:(?!Item\sB).){50,}", subject, re.I):
f.extend(match.group()+"\n")
从另一个StackOverflow回答中得出,其中项目A将是&#39;:&#39;因为分支长度总是出现在a之后,而B项将是&#39;,&#39;或者&#39;)&#39;或者&#39 ;;&#39;因为这有三个字符划分它,但我没有经验足够的正则表达式来做到这一点。
在这种情况下,通过使用分支长度为0,我希望代码输出[&#39; BMNH703458a&#39;,&#39; BMNH703458b&#39;]。如果我可以改变它,也包括通过用户定义的值0.01的分支长度加入的ID,这将是非常有用的。
如果有人有任何意见,或者可以指出我有用的答案,我将非常感激。
答案 0 :(得分:2)
好的,这是一个正则表达式,只提取数字(带有可能的小数):
\b[0-9]+(?:\.[0-9]+)?\b
\b
确保旁边的数字周围没有其他数字,字母或下划线。它被称为单词边界。
[0-9]+
匹配多个数字。
(?:\.[0-9]+)?
是一个可选组,意味着它可能匹配也可能不匹配。如果在第一个[0-9]+
之后有一个点和数字,那么它将匹配那些。否则,它不会。该组本身匹配一个点,至少1位数。
您可以将其与re.findall
一起使用,将所有匹配项放入列表中:
import re
NewickTree = ['(BMNH833953:0.16529463651919140688,(((BMNH833883:0.22945757727367316336,(BMNH724182a:0.18028180766761139897,(BMNH724182b:0.21469677818346077913,BMNH724082:0.54350916483644962085):0.00654573856803835914):0.04530853441176059537):0.02416511342888815264,(((BMNH794142:0.21236619242575086042,(BMNH743008:0.13421900772403019819,BMNH724591:0.14957653992840658219):0.02592135486124686958):0.02477670174791116522,BMNH703458a:0.22983459269245612444):0.00000328449424529074,BMNH703458b:0.29776257618061197086):0.09881729077887969892):0.02257522897558370684,BMNH833928:0.21599133163597591945):0.02365043128986757739,BMNH724053:0.16069861523756587274):0.0;']
pattern = re.compile(r"\b[0-9]+(?:\.[0-9]+)?\b")
for tree in NewickTree:
branch_lengths = pattern.findall(tree)
# Do stuff to the list branch_lengths
print(branch_lengths)
对于此列表,您可以打印出来:
['0.16529463651919140688', '0.22945757727367316336', '0.18028180766761139897',
'0.21469677818346077913', '0.54350916483644962085', '0.00654573856803835914',
'0.04530853441176059537', '0.02416511342888815264', '0.21236619242575086042',
'0.13421900772403019819', '0.14957653992840658219', '0.02592135486124686958',
'0.02477670174791116522', '0.22983459269245612444', '0.00000328449424529074',
'0.29776257618061197086', '0.09881729077887969892', '0.02257522897558370684',
'0.21599133163597591945', '0.02365043128986757739', '0.16069861523756587274',
'0.0']
答案 1 :(得分:2)
我知道您的问题已得到解答,但如果您希望将数据作为嵌套列表而不是扁平字符串:
import re
import pprint
a="(BMNH833953:0.16529463651919140688,(((BMNH833883:0.22945757727367316336,(BMNH724182a:0.18028180766761139897,(BMNH724182b:0.21469677818346077913,BMNH724082:0.54350916483644962085):0.00654573856803835914):0.04530853441176059537):0.02416511342888815264,(((BMNH794142:0.21236619242575086042,(BMNH743008:0.13421900772403019819,BMNH724591:0.14957653992840658219):0.02592135486124686958):0.02477670174791116522,BMNH703458a:0.22983459269245612444):0.00000328449424529074,BMNH703458b:0.29776257618061197086):0.09881729077887969892):0.02257522897558370684,BMNH833928:0.21599133163597591945):0.02365043128986757739,BMNH724053:0.16069861523756587274):0.0;"
def tokenize(str):
for m in re.finditer(r"\(|\)|[\w.:]+", str):
yield m.group()
def make_nested_list(tok, L=None):
if L is None: L = []
while True:
try: t = tok.next()
except StopIteration: break
if t == "(": L.append(make_nested_list(tok))
elif t == ")": break
else:
i = t.find(":"); assert i != -1
if i == 0: L.append(float(t[1:]))
else: L.append([t[:i], float(t[i+1:])])
return L
L = make_nested_list(tokenize(a))
pprint.pprint(L)
答案 2 :(得分:2)
有几个Python库支持newick格式。 ETE toolkit允许读取newick字符串并使用树作为Python对象进行操作:
from ete2 import Tree
tree = Tree(newickFile)
print tree
几个newick子格式可以是choosen,并且即使用科学记数法表示分支距离也会被解析。
from ete2 import Tree
tree = Tree("(A:3.4, (B:0.15E-10,C:0.0001):1.5E-234);")