我必须处理一个15MB的txt文件(核酸序列)并找到所有不同的子串(大小为5)。例如:
ABCDEF
会返回2,因为我们有ABCDE和BCDEF,但是
AAAAAA
将返回1.我的代码:
control_var = 0
f=open("input.txt","r")
list_of_substrings=[]
while(f.read(5)!=""):
f.seek(control_var)
aux = f.read(5)
if(aux not in list_of_substrings):
list_of_substrings.append(aux)
control_var += 1
f.close()
print len(list_of_substrings)
另一种方法会更快(而不是直接比较文件中的字符串)吗?
答案 0 :(得分:1)
import Counter, re
contents = open('input.txt', 'r').read()
counter = Counter.Counter(re.findall('.{5}', contents))
print len(counter)
<强>更新强>
我认为user590028提供了一个很好的解决方案,但这是另一种选择:
contents = open('input.txt', 'r').read()
print set(contents[start:start+5] for start in range(0, len(contents) - 4))
# Or using a dictionary
# dict([(contents[start:start+5],True) for start in range(0, len(contents) - 4)]).keys()
答案 1 :(得分:1)
根据您对合法子字符串的定义,这是一个可能的解决方案:
import re
regex = re.compile(r'(?=(\w{5}))')
with open('input.txt', 'r') as fh:
input = fh.read()
print len(set(re.findall(regex, input)))
当然,您可以将\w
替换为您认为合适的任何内容,以符合子字符串中的合法字符。例如[A-Za-z0-9]
将匹配所有字母数字字符。
这是一个执行示例:
>>> import re
>>> input = "ABCDEF GABCDEF"
>>> set(re.findall(regex, input))
set(['GABCD', 'ABCDE', 'BCDEF'])
编辑:根据上面的评论,文件中的所有字符都有效,不包括最后一个(\n
),似乎没有真正需要定期这里的表达式和迭代方法要快得多。您可以使用此代码自行对其进行基准测试(请注意,我稍微修改了函数以反映有关有效子字符串定义的更新):
import timeit
import re
FILE_NAME = r'input.txt'
def re_approach():
return len(set(re.findall(r'(?=(.{5}))', input[:-1])))
def iter_approach():
return len(set([input[i:i+5] for i in xrange(len(input[:-6]))]))
with open(FILE_NAME, 'r') as fh:
input = fh.read()
# verify that the output of both approaches is identicle
assert set(re.findall(r'(?=(.{5}))', input[:-1])) == set([input[i:i+5] for i in xrange(len(input[:-6]))])
print timeit.repeat(stmt = re_approach, number = 500)
print timeit.repeat(stmt = iter_approach, number = 500)
答案 2 :(得分:0)
您可以使用字典,其中每个键都是子字符串。它将处理重复,你可以在最后计算密钥。
所以:读一遍文件,将每个子字符串存储在字典中,这将处理查找重复的子字符串&amp;计算不同的。
答案 3 :(得分:0)
一次性读取更多i / o效率,并且使用dict()将比在列表中测试存在更快。类似的东西:
fives = {}
buf = open('input.txt').read()
for x in xrange(len(buf) - 4):
key = buf[x:x+5]
fives[key] = 1
for keys in fives.keys():
print keys