将字符串拆分为"x"长度的组

-1 投票
6 回答
1229 浏览
提问于 2025-04-18 16:27

我在想,如果我有一个从文本文件中读取的字符串,最有效的方法是什么来把它分成每5个字符一组?比如说:

我有一个叫做 dna.txt 的文本文件,里面的内容是:

>human
ACCGTGAAAAACGTGAGTATA
>mouse
ACCAAAAGTGTAT

然后我有一个 Python 脚本,它会存储这个文本文件的第2行和第4行。

import linecache
f = open("dna.txt")
sequence_1 = linecache.getline('dna.txt', 2)
sequence_2 = linecache.getline('dna.txt', 4)
f.close()

这个程序的目标是打印出:

>human
ACCGT
GAAAA
ACGTG
AGTAT
A
>mouse
ACCAA
AAGTG
TAT

就像我之前说的,我一直在努力想出一种有效的方法来分割这两个字符串,但一直没有成功。非常感谢任何帮助!

6 个回答

0

你可以很简单地用生成器表达式或者列表推导式来实现这个功能,特别是在旧版本的Python中。对于任何字符串 s 和字符串中的索引 i,表达式 s[i:i+5] 会返回从位置 i 开始的最长5个字符的子字符串。

如果 i+5 超过了字符串的末尾,使用这种切片的方式会自动处理这个问题,不会报错,而是返回它能找到的最长字符串。

所以这个表达式

[sequence_1[i:i+5] for i in range((0, len(sequence_1), 5)]

应该能给你一个你需要的子字符串列表。

0

在使用这个之前,先看看我写这个的时候其他人给出的答案。

这个算法很简单,但效率不是很好。

虽然不是特别高效,但你可以用一个简单的循环来实现。

str = "abcdefghijlkmnopqrstuvwxyz"
length = len(str)
i = 0
subs = []
while (i < length):
    subs[i/5] = str[i:i+5]
    i += 5

最终每个subs的索引应该包含五个字符分组。

0
In [1]: import re

In [2]: s = "ACCGTGAAAAACGTGAGTATA"

In [3]: print("\n".join(re.findall("\w{5}|\w+",s))) 
ACCGT
GAAAA
ACGTG
AGTAT
A

re.findall("\w{5}|\w+",s) 这个代码的意思是从字符串中找出连续的5个字符,或者找出一个或多个字符。

这里有一些时间记录:

In [72]: %timeit "\n".join(groupdna(s,5))
100000 loops, best of 3: 3.5 µs per loop

In [73]: timeit ('\n'.join(splitn(s, 5)))
100000 loops, best of 3: 2.22 µs per loop

In [74]: %timeit re.sub(r'(.{5})(?!$)', r'\g<1>\n', s)
100000 loops, best of 3: 5.24 µs per loop

In [75]: %timeit ("\n".join(re.findall("\w{5}|\w+",s)))
100000 loops, best of 3: 2.16 µs per loop
3

这段代码可以帮助你入门:

human = "ACCGTGAAAAACGTGAGTATA"
print(' '.join(human[i:i+5] for i in range(0, len(human), 5)))

你可以很简单地把这个变成一个生成器,接受 human5 作为参数,然后输出子字符串:

def splitn(s, n):
    for i in range(0, len(s), n):
        yield s[i:i+n]

print(' '.join(splitn("ACCGTGAAAAACGTGAGTATA", 5)))
1
>>> human = 'ACCGTGAAAAACGTGAGTATA'
>>> mouse = 'ACCAAAAGTGTAT'
>>> import re
>>> def format_dna(s):
...     return re.sub(r'(.{5})(?!$)', r'\g<1>\n', s)
...
>>> print(format_dna(human))
ACCGT
GAAAA
ACGTG
AGTAT
A
>>> print(format_dna(mouse))
ACCAA
AAGTG
TAT

re.sub 是用来在字符串中进行正则表达式替换的。

(.{5})(?!$) 是用来匹配的模式。\g<1>\n 是用来替换的模式。

.{5} 可以匹配任意五个字符。加上括号 (.{5}) 后,它就变成了一个捕获组。

$ 表示字符串的结尾。(?!$) 是一种负向前瞻,它的作用是防止匹配到最后一组字符,如果字符串的长度是五的倍数的话(这样会导致在字符串末尾多加一个换行符)。

\g<1> 是一个反向引用,指的是第一个(也是唯一的)捕获组。

所以这段话的意思是:当你看到一连串的五个字符(并且这些不是最后五个字符),就把它们替换成这五个字符加上一个换行符。

撰写回答