简体   繁体   English

扫描列表连续5个大于x的值

[英]Scanning list for 5 consecutive values greater than x

I want to scan a large list for consecutive values that are greater than x. 我想扫描大型列表中的连续值大于x。 This example x is greater than 1.0. 此示例x大于1.0。

For example, 例如,

my_list = [0.2, 0.1, 0.3, 1.1, 0.7, 0.5, 1.2, 1.3, 1.4, 1.2, 1.9, 1.1, 0.2, 1.3, 1.5, 1.4, 1.2, 1.1, 0.2, 1.3, 0.1., 1.6, 0.2, 0.5, 1.0, 1.1, 0.2]

I can subset this list by 我可以按此列出这个列表

for i in range(0, len(my_list)):
    subset = my_list[i:i+5]

so I get 所以我明白了

[0.2, 0.1, 0.3, 1.1, 0.7]
[0.1, 0.3, 1.1, 0.7, 0.5]
[0.3, 1.1, 0.7, 0.5, 1.2]
[1.1, 0.7, 0.5, 1.2, 1.3]
[0.7, 0.5, 1.2, 1.3, 1.4]
[0.5, 1.2, 1.3, 1.4, 1.2]
[1.2, 1.3, 1.4, 1.2, 1.9] <-- values I want
[1.3, 1.4, 1.2, 1.9, 1.1] <-- values I want
[1.4, 1.2, 1.9, 1.1, 0.2]
[1.2, 1.9, 1.1, 0.2, 1.3]
[1.9, 1.1, 0.2, 1.3, 1.5]
[1.1, 0.2, 1.3, 1.5, 1.4]
[0.2, 1.3, 1.5, 1.4, 1.2]
[1.3, 1.5, 1.4, 1.2, 1.1] <-- values I want

What is the best way to do this? 做这个的最好方式是什么?

You can do that as follows: 你可以这样做:

my_list = [0.2, 0.1, 0.3, 1.1, 0.7, 0.5, 1.2, 1.3, 1.4, 1.2, 1.9, 1.1, 0.2, 1.3, 1.5, 1.4, 1.2, 1.1, 0.2, 1.3, 0.1, 1.6, 0.2, 0.5, 1.0, 1.1, 0.2]

x = 1

result = [my_list[i:i+5] for i in range(len(my_list)-4) if all(i > x for i in my_list[i:i+5])]

Here's an itertools based approach that won't need any extra memory and returns results as a generator: 这是一个基于itertools的方法,不需要任何额外的内存,并将结果作为生成器返回:

from itertools import tee, islice

def find_consecutive(the_list, threshold, count=5):
    my_iters = tee(the_list, count)
    for i, it in enumerate(my_iters):
        next(islice(it, i, i), None)
    return (f for f in zip(*my_iters) if all(x > threshold for x in f))

my_list = [0.2, 0.1, 0.3, 1.1, 0.7, 0.5, 1.2, 1.3, 1.4, 1.2, 1.9, 1.1, 0.2, 1.3, 1.5, 1.4, 1.2, 1.1, 0.2, 1.3, 0.1, 1.6, 0.2, 0.5, 1.0, 1.1, 0.2]
list(find_consecutive(my_list, 1.0))
# [(1.2, 1.3, 1.4, 1.2, 1.9),
# (1.3, 1.4, 1.2, 1.9, 1.1),
# (1.3, 1.5, 1.4, 1.2, 1.1)]

The function is parameterized by threshold and count so you can look for any N consecutive values. 该功能通过阈值和计数进行参数化,因此您可以查找任何N个连续值。 You could even factor out the condition by passing in a function for that instead of just a threshold value. 您甚至可以通过传入函数而不仅仅是阈值来分解条件。

>>>my_list = [0.2, 0.1, 0.3, 1.1, 0.7, 0.5, 1.2, 1.3, 1.4, 1.2, 1.9,
1.1, 0.2, 1.3, 1.5, 1.4, 1.2, 1.1, 0.2, 1.3, 0.1, 1.6, 0.2, 0.5, 1.0,1.1, 0.2]

>>>x = 1.0
>>>for i in range(0, len(my_list)):
       subset = my_list[i:i+5]
       if(all(item >x for item in subset)):
           print subset

[1.2, 1.3, 1.4, 1.2, 1.9]
[1.3, 1.4, 1.2, 1.9, 1.1]
[1.3, 1.5, 1.4, 1.2, 1.1]

It might save some time to keep a counter so you don't need to keep on checking values that are already checked. 保留计数器可能会节省一些时间,因此您无需继续检查已检查的值。 Here n=5 这里n=5

def scan_k(arr, val,n):
    counter = 0
    results = set()
    for i in range(len(arr)):
        if arr[i] > val:
            counter +=1
        else:
            counter = 0
            continue
        if counter >= n:
            results.add(arr[(i-n+1):i])
return(results)

Here's a fast solution using a generator function and a variable that keeps track of the number encountered so far: 这是一个快速的解决方案,使用生成器函数和一个跟踪到目前为止遇到的数字的变量:

def find_n_consecutive_greater_than_x(mylist, n, x):
    num_greater_than_x = 0
    for index, val in enumerate(mylist):
        if val > x:
            num_greater_than_x += 1
            if num_greater_than_x == n:
                yield tuple(mylist[index-n+1:index+1])
                num_greater_than_x -= 1
        else:
            num_greater_than_x = 0

mylist = [2]*6
n = 5
x = 1.0

print(list(find_n_consecutive_greater_than_x(mylist, n, x)))
# [(2, 2, 2, 2, 2), (2, 2, 2, 2, 2)]

This will be much faster than any solution that computes all slices of length 5 of a given list because it only processes each element once and avoids the creation of objects, which is painfully slow in most Python implementations. 这将是比计算给定列表的长度为5的所有片,因为它只能处理每个元素一次,避免了创建对象,这是大多数Python实现极为缓慢的任何解决方案快得多

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM