编写一个适配器删除工具,关于忽略序列大小写的建议

writing an adaptor removal tool, advice on ignoring case on the sequence

我正在学习如何编码。除其他外,我需要编写适配器删除工具的代码。除了序列是大小写混合的情况外,我的脚本工作正常。 适配器序列== TATA 序列 == TAtaGATTACA

这是移除适配器的函数

elif operation == "adaptor-removal":

    adaptor = args.adaptor 
    reads =  sequences(args.input, format)
    num_reads = len(reads)
    bases = "".join([read["seq"] for read in reads])
    adaptors_found = 0

    for read in reads:
        for i, j in read.items():
            if i == "seq":
                if j.startswith(adaptor.upper()) or j.startswith(adaptor.lower()):
                    adaptors_found += 1
                    j = j.replace(adaptor.upper(), "", 1) 
                    j = j.replace(adaptor.lower(), "", 1)                 
            args.output.write("%s\n" % j)
    print_summary(operation)    
    print("%s adaptors found" % adaptors_found)

我试过:

if j.startswith(adaptor,re.I):

但是不起作用,我不太明白为什么。有经验的人可以指导我吗?

非常感谢

假设 jTAtaGATTACA 并且 adaptorTATA

j.startswith(adaptor.upper())是真的吗?不,因为 j 不是以 TATA.

开头

j.startswith(adaptor.lower())是真的吗?不,因为 j 不是以 tata.

开头

不区分大小写地比较两个字符串的最简单方法是将它们转换为相同的大小写,大写或小写,然后像区分大小写一样比较这两个字符串。选择大写还是小写都无所谓,只要两者都选择相同即可。

j.lower().startswith(adaptor.lower())是真的吗?是的,因为 j.lower()tata.

开头

此外,请注意您的两个 .replace() 调用:其中一个可能最终会删除 j 中的文本,我认为您不希望这样。如果你只想 trim 适配器关闭 j 的前面,你最好使用字符串切片:

                if j.lower().startswith(adaptor.lower()):
                    adaptors_found += 1
                    j = j[len(adaptor):]

最后你也问为什么

if j.startswith(adaptor,re.I):

没有按照您的意愿行事。答案是,如果你给.startswith()传递第二个参数,这个第二个参数的值就是你搜索的起始位置,而不是控制匹配的标志:

"abcd".startswith("cd")           # False
"abcd".startswith("cd", 2)        # True

正好re.I可以转为整数2,所以下面也是True,虽然看起来很奇怪:

"abcd".startswith("cd", re.I)