![](/img/trans.png)
[英]What is the most efficient algorithm to find the midpoint of the index of a repeated sequence of numbers?
[英]Efficient way to find the index of repeated sequence in a list?
我在python中有一个很大的数字列表,我想编写一个函数来查找列表中的相同数字重复n次以上的部分。 例如,如果n为3,则对于以下示例,我的函数应返回以下结果:
当应用于example = [1,2,1,1,1,1,2,3]时,该函数应返回[(2,6)],因为example [2:6]是包含所有相同值的序列。
当应用于example = [0,0,0,7,3,2,2,2,2,1]时,该函数应返回[(0,3),(5,9)],因为两个example [0:3 ]和example [5:9]包含相同值的重复序列。
当应用于example = [1,2,1,2,1,2,1,2,1,2]时,该函数应返回[],因为不存在三个或三个以上相同编号元素的序列。
我知道我可以编写一堆循环来获取所需的内容,但这似乎效率不高,我想知道是否有更简单的选择来获取所需的内容。
使用itertools.groupby
并enumerate
:
>>> from itertools import groupby
>>> n = 3
>>> x = [1,2,1,1,1,1,2,3]
>>> grouped = (list(g) for _,g in groupby(enumerate(x), lambda t:t[1]))
>>> [(g[0][0], g[-1][0] + 1) for g in grouped if len(g) >= n]
[(2, 6)]
>>> x = [0,0,0,7,3,2,2,2,2,1]
>>> grouped = (list(g) for _,g in groupby(enumerate(x), lambda t:t[1]))
>>> [(g[0][0], g[-1][0] + 1) for g in grouped if len(g) >= n]
[(0, 3), (5, 9)]
要了解groupby:只需意识到每次迭代都会返回键的值(该键用于对iterable的元素进行分组),以及一个新的lazy-iterable(将在组中进行迭代)。
>>> list(groupby(enumerate(x), lambda t:t[1]))
[(0, <itertools._grouper object at 0x7fc90a707bd0>), (7, <itertools._grouper object at 0x7fc90a707ad0>), (3, <itertools._grouper object at 0x7fc90a707950>), (2, <itertools._grouper object at 0x7fc90a707c10>), (1, <itertools._grouper object at 0x7fc90a707c50>)]
您可以按照当前算法在单个循环中执行此操作:
def find_pairs (array, n):
result_pairs = []
prev = idx = 0
count = 1
for i in range (0, len(array)):
if(i > 0):
if(array[i] == prev):
count += 1
else:
if(count >= n):
result_pairs.append((idx, i))
else:
prev = array[i]
idx = i
count = 1
else:
prev = array[i]
idx = i
return result_pairs
然后调用这样的函数: find_pairs(list, n)
。 这是执行此任务的最有效方法,因为它具有复杂度O(len(array))。 我认为这很容易理解,但是如果您有任何疑问,请提出。
您可以使用它。 请注意,关于n的作用,您的问题模棱两可。 我在这里假设应该匹配一系列n个相等的值。 如果它至少应具有n + 1个值,则将>=
替换为>
:
def monotoneRanges(a, n):
idx = [i for i, v in enumerate(a) if not i or a[i-1] != v] + [len(a)]
return [r for r in zip(idx, idx[1:]) if r[1] >= r[0]+n]
# example call
res = monotoneRanges([0,0,0,7,3,2,2,2,2,1], 3)
print(res)
输出:
[(0, 3), (5, 9)]
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.