在比较函数中,我基本上在长二进制对象中寻找一个模式(例如“AAA”)(例如,aaaAAAbbbBBB)
我正在通过文件向后工作(我知道匹配将比结束更接近结束),向正在检查匹配的变量添加1个字节:
1. aaaAAAbbbBB[B]
2. aaaAAAbbbB[BB]
3. aaaAAAbbb[BBB]
4. aaaAAAbb[bBBB]
5. ...
n. aaa[AAAbbbBBB]
找到匹配,偏移= -n
鉴于我知道我的模式是3个元素长,我想知道我是否可以简单地窗口搜索变量而不是递增它 - 当匹配列表中的+1,000,000个元素时它变得很慢 - 窗口视图相同数据将是:
1. aaaAAAbbb[BBB]
2. aaaAAAbb[bBB]B
3. aaaAAAb[bbB]BB
4. aaaAAA[bbb]BBB
5. ...
n. aaa[AAA]bbbBBB
找到匹配,偏移= -n
我目前的搜索结果如下:
if marker in f_data[-counter:]:
offset = (len(f_data)-counter)+len(marker)
return offset
在MATLAB中,我会使用数组寻址来遍历数组,(例如调用window = a [5:8],window = a [4:7]等),但我不认为这在Python中是可行的(2.7)
我可以看到一些使用滑动窗口的建议,(Rolling or sliding window iterator in Python - 这看起来像一个紧密的匹配)但我看不到如何实现它或他们引用我不知道如何的库使用。
这是否有内置功能?
答案 0 :(得分:5)
为什么不使用rfind()
或rindex()
?
haystack = "aaaAAAbbbBBB"
needle = "AAA"
pos = haystack.rfind(needle)
if pos >= 0:
print "found at", pos - len(haystack)
else:
print "not found"
答案 1 :(得分:0)
两件事:
(1)标准字符串类型包含字节,您可以使用正则表达式。我可以建议你将对象啜饮成一个字符串,然后进行正则表达式搜索。
(2)如果你确实想要这么做,那就http://docs.python.org/library/itertools.html#itertools.groupby
答案 2 :(得分:0)
我认为这会使用你提到的window()迭代器函数。
>>> l = "ABCABACAAASSD"
>>> from itertools import islice
>>>
>>> def window(seq, n=2):
... "Returns a sliding window (of width n) over data from the iterable"
... " s -> (s0,s1,...s[n-1]), (s1,s2,...,sn), ... "
... it = iter(seq)
... result = tuple(islice(it, n))
... if len(result) == n:
... yield result
... for elem in it:
... result = result[1:] + (elem,)
... yield result
...
>>>
>>> data = [c for c in l] # get each byte/charactor as separate item in list
>>> data
['A', 'B', 'C', 'A', 'B', 'A', 'C', 'A', 'A', 'A', 'S', 'S', 'D']
>>> for idx, elements in enumerate(window(reversed(data), n=3)):
... section = "".join(elements)
... if section == "AAA":
... print "found at {}!".format(idx)
...
found at 3!
>>>
解释:
reversed()
接受一个列表并返回一个迭代器,其元素的顺序相反window()
接受一个可迭代对象(list,tuple,iterator)并返回n
个元素,一次移动索引1元素。enumerate()
接受一个迭代,只需附加一个计数器,因此它将返回计数器/位置和给定的元素项。