Python 巨蟒;加窗;通过二进制对象的迭代?
在比较函数中,我基本上是在一个长的二进制对象(例如aaaabbbbbb)中寻找一个模式(例如“AAA”) 我正在向后查看文件(我知道匹配将更接近结尾而不是开始),向正在检查匹配的变量添加1个字节:Python 巨蟒;加窗;通过二进制对象的迭代?,python,iterator,Python,Iterator,在比较函数中,我基本上是在一个长的二进制对象(例如aaaabbbbbb)中寻找一个模式(例如“AAA”) 我正在向后查看文件(我知道匹配将更接近结尾而不是开始),向正在检查匹配的变量添加1个字节: 1. aaaAAAbbbBB[B] 2. aaaAAAbbbB[BB] 3. aaaAAAbbb[BBB] 4. aaaAAAbb[bBBB] 5. ... n. aaa[AAAbbbBBB] 找到匹配项,偏移量=-n 鉴于我知道我的模式有3个元素长,我想知道我是否可以简单地打开搜索变量的窗口,
1. aaaAAAbbbBB[B]
2. aaaAAAbbbB[BB]
3. aaaAAAbbb[BBB]
4. aaaAAAbb[bBBB]
5. ...
n. aaa[AAAbbbBBB]
找到匹配项,偏移量=-n
鉴于我知道我的模式有3个元素长,我想知道我是否可以简单地打开搜索变量的窗口,而不是增加它-当匹配在列表中+1000000个元素时,它会变得非常慢-相同数据的窗口视图将是:
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)中不可能这样做
我可以看到一些关于使用滑动窗口的建议(这看起来非常匹配),但我看不到如何实现它,或者它们引用了我不知道如何使用的lib
是否有用于执行此操作的内置函数 有两件事:
(1) 标准字符串类型保存字节,您可以将正则表达式与此一起使用。我可以建议您将对象拼成字符串,并执行正则表达式搜索
(2) 如果你真的想用艰难的方式去做,有两件事:
(1) 标准字符串类型保存字节,您可以将正则表达式与此一起使用。我可以建议您将对象拼成字符串,并执行正则表达式搜索
(2) 如果您确实想以艰难的方式完成,那么为什么不使用
rfind()
或rindex()
为什么不直接使用
rfind()
或rindex()
我认为这使用了您提到的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()
接受一个iterable并简单地附加一个计数器,因此它将返回计数器/位置和给定的元素项enumerate()
>>> 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()
接受一个iterable并简单地附加一个计数器,因此它将返回计数器/位置和给定的元素项enumerate()
rfind
从右侧搜索。如果需要最左边的匹配项,请使用查找。哦,这很有用,谢谢。大海捞针可能有n根,但我只需要最后一根——你如何处理多个匹配?@JayGattusorfind
从右侧搜索。如果您需要最左边的匹配,请使用查找
。谢谢,我希望有一天能遇到这样的代码并理解它!。。。我从根本上怀疑我在这个过程中走错了方向。谢谢你,我希望有一天能遇到这样的代码并理解它!。。。我从根本上怀疑我在这个过程中走错了方向。谢谢,我确实考虑过RegEx,但我有多个匹配案例,我只需要最后一个,当时(在我知道匹配有多深之前),我的方法似乎是合理的。我怀疑我做事情的方式不对@JayGattuso我不明白为什么只需要最后一个就可以排除正则表达式匹配,或者实际上是rfind
。排除的原因更多的是我不知道如何处理多重匹配场景,而不是工具本身的问题……)谢谢,我确实考虑过RegEx,但我有多个匹配案例,我只需要最后一个,当时(在我知道匹配有多深之前),我的方法似乎是合理的。我怀疑我做事情的方式不对@JayGattuso我不明白为什么只需要最后一个就可以排除正则表达式匹配,或者实际上是rfind
。排除的原因更多的是我不知道如何处理多重匹配场景,而不是工具本身的问题……)