【问题标题】:Elegant parsing of text-based key-value list基于文本的键值列表的优雅解析
【发布时间】:2014-04-02 23:43:45
【问题描述】:

我正在为基于文本的序列比对/映射 (SAM) 文件编写解析器。其中一个字段是键值对的串联列表,包括一个字母字符和一个整数(整数在前)。我有工作代码,但感觉有点笨拙。解析这种格式的优雅模式是什么?谢谢。

输入:

record['cigar_str'] = '6M1I69M1D34M'

期望的输出:

record['cigar'] = [
    {'type':'M', 'length':6},
    {'type':'I', 'length':1},
    {'type':'M', 'length':69},
    {'type':'D', 'length':1},
    {'type':'M', 'length':34}
]

编辑:我目前的方法

cigarettes = re.findall('[\d]{0,}[A-Z]{1}', record['cigar_str'])
for cigarette in cigarettes:
    if cigarette[-1] == 'I':
        errors['ins'] += int(cigarette[:-1])
    ...

【问题讨论】:

  • 你能展示你已经拥有的东西吗?也许它实际上是你能得到的最好的......
  • 无关,但请注意cigarette[-1] is 'I' 肯定不是您想要的。你想要cigarette[-1] == 'I'。在与None 进行比较时,您应该使用is 运算符(当然这是一个概括,但如果您发现自己使用is,您应该问自己为什么并确定它是否真的如此你想要什么)。
  • @SethMMorton 谢谢!我怀疑这是一个坏习惯。
  • 是的。 is 检查两个对象的 id 是否相同,除非您正在做一些花哨(或神奇)的事情,否则这很少是您想要的。 == 检查两个对象的值是否相同,这在几乎 100% 的情况下都是您想要的。

标签: python regex parsing bioinformatics


【解决方案1】:

这是我要做的:

>>> import re
>>> s = '6M1I69M1D34M'
>>> matches = re.findall(r'(\d+)([A-Z]{1})', s)
>>> import pprint
>>> pprint.pprint([{'type':m[1], 'length':int(m[0])} for m in matches])
[{'length': 6, 'type': 'M'},
 {'length': 1, 'type': 'I'},
 {'length': 69, 'type': 'M'},
 {'length': 1, 'type': 'D'},
 {'length': 34, 'type': 'M'}]

它与您所拥有的非常相似,但它使用正则表达式组来梳理匹配的各个组成部分。

【讨论】:

  • 正则表达式分组加上生成器似乎是我所追求的。谢谢。
猜你喜欢
  • 2011-01-13
  • 2015-02-18
  • 2010-09-18
  • 2011-06-11
  • 2019-01-29
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多