Biopython类实例 - 来自Entrez.read的输出:我不知道如何操作输出

时间:2012-07-04 04:00:48

标签: python class biopython

我正在尝试从Pubmed下载一些xml - 没有问题,Biopython很棒。问题是我真的不知道如何操纵输出。我想将大部分已解析的xml放入sql数据库,但我不熟悉输出。对于某些事情,我可以将解析的xml称为字典,但对于其他人来说,它似乎并不是那么直接。

from Bio import Entrez
Entrez.email="xxxxxxxxxxxxx@gmail.com"
import sqlite3 as lite
handle=Entrez.efetch(db='pubmed',id='22737229', retmode='xml')
record = Entrez.read(handle)

如果我想找到标题,我可以这样做:

title=record[0]['MedlineCitation']['Article']['ArticleTitle']

但解析对象的类型是一个类:

>>> type(record)
<class 'Bio.Entrez.Parser.ListElement'>
>>>r=record[0]
>>>type(r)
<class 'Bio.Entrez.Parser.DictionaryElement'>
>>> r.keys()
[u'MedlineCitation', u'PubmedData']

这使得我认为必须有一种更简单的方法来做到这一点,而不是将其用作字典。但是当我尝试:

>>> r.MedlineCitation

Traceback (most recent call last):
  File "<pyshell#67>", line 1, in <module>
    r.MedlineCitation
AttributeError: 'DictionaryElement' object has no attribute 'MedlineCitation'

它不起作用。我显然可以将它用作字典,但后来我遇到了问题。

真正的问题是在使用字典时尝试从记录中获取某些信息:

>>> record[0]['MedlineCitation']['PMID']
StringElement('22737229', attributes={u'Version': u'1'})

这意味着我不能只是把它(这是一个技术术语;)放入我的sql数据库但需要转换它:

>>> t=record[0]['MedlineCitation']['PMID']
>>> t
StringElement('22737229', attributes={u'Version': u'1'})
>>> int(t)
22737229
>>> str(t)
'22737229'

总而言之,我很高兴Entrez.read()提供的信息深度,但我不确定如何轻松地使用生成的类实例中的信息。通常你可以做像

这样的事情
record.MedlineCitation

但它不起作用。

干杯

惠顿

2 个答案:

答案 0 :(得分:4)

Entrez.read()方法将返回一个由ListElementDictionaryElement组成的嵌套数据结构。有关更多信息,请查看read method in the biopython source的文档,我将在下面摘录并解释:

def read(handle, validate=True):

This function parses an XML file created by NCBI's Entrez Utilities,
returning a multilevel data structure of Python lists and dictionaries.
...
the[se] data structure[s] seem to consist of generic Python lists,
dictionaries, strings, and so on, [but] each of these is actually a class
derived from the base type. This allows us to store the attributes
(if any) of each element in a dictionary my_element.attributes, and
the tag name in my_element.tag.

该软件包的作者Michiel de Hoon也花了一些时间在Parser.py源文件的顶部,在Entrez中讨论他的motivations for representing the XML documents using the custom ListElements and DictionaryElements

如果您非常好奇,还可以阅读源中ListElementDictionaryElementStructureElement类的精彩声明。我会破坏这个惊喜,让你知道它们是基本的Python数据类型的非常轻的包装器,并且它们的行为几乎与它们的基础基本数据类型完全相同,除了它们有一个新属性attributes,它捕获read正在解析的文档中每个XML节点的XML属性(键和值)。

所以你的问题的基本答案是没有“简单”的方法来使用点运算符语法来解决DictionaryElement的键。如果你有一个字典元素d,那么:

>>> d
DictElement({'first_name': 'Russell', 'last_name': 'Jones'}, attributes={'occupation': 'entertainer'})

您可以阅读first_name的唯一内置方法是使用普通的python词典API,例如:

>>> d['first_name']
'Russell'
>>> d.get('first_name')
'Russell'
>>> d.get('middle_name', 'No Middle Name')
'No Middle Name'

不要灰心,这真的不是那么糟糕。如果你想获取某些节点并将它们插入到sqlite数据库的行中,你可以编写以DictElement作为输入的小方法,并返回sqlite可以接受的输出。如果您遇到此问题,请随意发布另一个问题。

答案 1 :(得分:1)

我不确定这是否正确,但我相信这个记录是&#39;是一个词典列表。所以你需要使用循环来获取每个字典

这样的东西
for r in record:
    r['MedlineCitation']