Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/python/362.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
python在列表中查找正元素的范围_Python_List - Fatal编程技术网

python在列表中查找正元素的范围

python在列表中查找正元素的范围,python,list,Python,List,我有一个清单,例如 [0,0,0,12,34,86,0,0,0,95,20,1,6,0,0,0,11,24,67,0,0,0] 我想找到元素为正的开始和结束位置: [[3,5],[9,12],[16,18]] 在python中实现这一点的最佳方法是什么? (python中的内置函数,如:find、lambda、itemgetter等。)用于解决方案的原始:( 不确定范围是否可以离开阵列的末端 def get_positive_ranges(a): in_range = False

我有一个清单,例如

[0,0,0,12,34,86,0,0,0,95,20,1,6,0,0,0,11,24,67,0,0,0]
我想找到元素为正的开始和结束位置:

[[3,5],[9,12],[16,18]]
在python中实现这一点的最佳方法是什么?
(python中的内置函数,如:find、lambda、itemgetter等。)

用于解决方案的原始
:(


不确定范围是否可以离开阵列的末端

def get_positive_ranges(a):
    in_range = False
    result = []
    for i in range(len(a)):
        if not in_range:
            if a[i] > 0:
                in_range = True
                first = i
        else: # Inside a range
            if a[i] <= 0: # End of range
                in_range = False
                result.append([first, i - 1])
    if in_range: # Tidy
        result.append([first, i])
    return result

print(get_positive_ranges([0,0,0,12,34,86,0,0,0,95,20,1,6,0,0,0,11,24,67,0,0,0]))
print(get_positive_ranges([]))
print(get_positive_ranges([1]))
print(get_positive_ranges([0, 1]))
print(get_positive_ranges([0, 1, 0]))
def获取正量程(a):
范围内=错误
结果=[]
对于范围内的i(len(a)):
如果不在_范围内:
如果[i]>0:
范围内=真
第一个=我
否则:#在范围内
如果一个[i]有效

lst = [0, 0, 0, 12, 34, 86, 0, 0, 0, 95, 20, 1, 6, 0, 0, 0, 11, 24, 67, 0, 0, 0]

n = len(lst)

starting_points = [i for i in range(n) if lst[i] > 0 and (lst[i - 1] == 0 or i == 0)]
end_points = [next((i for i in range(j + 1, n) if lst[i] == 0), n) - 1 for j in starting_points]

print zip(starting_points, end_points)
输出

[(3, 5), (9, 12), (16, 18)]

这是一个numpy解决方案,不确定这是否比简单的for循环好;请参阅内联注释以获取解释

import numpy as np

a = np.array([0,0,0,12,34,86,0,0,0,95,20,1,6,0,0,0,11,24,67,0,0,0])

# get indices of non-zero elements in a
nze = a.nonzero()[0]

# check where the differences of these indices are unequal to one; there you have a jump to/from 0
nze_diff = np.where(np.diff(nze) > 1)[0] + 1

# if a starts with 0, add the index 0
if nze_diff[0] != 0:
    nze_diff = np.insert(nze_diff, 0, 0)

# store output
res = []

# loop through the indices and add the desired slices
for ix, i in enumerate(nze_diff):
    try:
        sl = nze[i:nze_diff[ix + 1]]
        res.append([sl[0], sl[-1]])
    # means we reached the end of nze_diff
    except IndexError:
        sl = nze[i:]
        res.append([sl[0], sl[-1]])   
如果为
a
运行,则会收到所需的输出:

[[3, 5], [9, 12], [16, 18]]
可能有比这更聪明的解决方案,但这可能会让你开始

如果您想获得整个范围,它可以简化一点:

res2 = []
for ix, i in enumerate(nze_diff):
    try:
        res2.append(nze[i:nze_diff[ix + 1]])
    except IndexError:
        res2.append(nze[i:])
然后,
res2
将是:

[array([3, 4, 5]), array([ 9, 10, 11, 12]), array([16, 17, 18])]

如果性能是关键,那么您应该使用很长的列表来测试哪种实现最快。无论如何,这是“索引无数组访问”版本,希望能提高速度。如果您喜欢,它使用
映射
lambda
索引(查找)
。当然,它使用

input = [0,0,0,12,34,86,0,0,0,95,20,1,6,0,0,0,11,24,67,0,0,0]
output = []

input2 = list(map(lambda x: x and (1, -1)[x < 0], input))  # mapping by 'math.sign'-like func
start = end = 0
while end < len(input2):
    try:
        start = input2.index(1, end + 1)
        end = input2.index(0, start) - 1
        output.append([start, end])
    except ValueError:
        break

if start >= end:
    output.append([start, len(input2) - 1])

print(output)  # [[3, 5], [9, 12], [16, 18]]
input=[0,0,0,12,34,86,0,0,0,95,20,1,6,0,0,0,11,24,67,0,0,0,0]
输出=[]
input2=list(映射(lambda x:x和(1,-1)[x<0],输入))#通过类似于函数的“数学符号”进行映射
开始=结束=0
当end=结束:
output.append([start,len(input2)-1])
打印(输出)#[[3,5]、[9,12]、[16,18]]

最后,
regex
version.)

input=[0,0,0,12,34,86,0,0,0,95,20,1,6,0,0,0,11,24,67,0,0,0,0]
input3=str(列表(
映射(lambda i_x:i_x[0]*(i_x[1]和(1,-1)[i_x[1]<0]),枚举(输入))
))
进口稀土
s=re.sub(r'([\[]0[\],])+','',输入3)
s=s.replace(“,”,“],[”)
如果s[-1:]!=']':
s=s[:-2]+']'
s='['+s[2:]
s=re.sub(r'[0-9]+,'','',s)
输出=列表(评估)
打印(输出)#[[3,5]、[9,12]、[16,18]]

这不是一个python问题,更多的是一个算法问题;)您必须告诉我们您尝试了什么Elahew什么阻止您为此编写
for
循环?是否也有负值?我想了解python中是否有内置函数来执行此操作。我的列表很长,并且使用了“for loop”时间效率不高!哦哦哦:。非常好!这是最快和最有效的一个。非常感谢@Sangbok Lee!
input = [0,0,0,12,34,86,0,0,0,95,20,1,6,0,0,0,11,24,67,0,0,0]
output = []

input2 = list(map(lambda x: x and (1, -1)[x < 0], input))  # mapping by 'math.sign'-like func
start = end = 0
while end < len(input2):
    try:
        start = input2.index(1, end + 1)
        end = input2.index(0, start) - 1
        output.append([start, end])
    except ValueError:
        break

if start >= end:
    output.append([start, len(input2) - 1])

print(output)  # [[3, 5], [9, 12], [16, 18]]
input = [0,0,0,12,34,86,0,0,0,95,20,1,6,0,0,0,11,24,67,0,0,0]

input3 = str(list(
  map(lambda i_x: i_x[0] * (i_x[1] and (1, -1)[i_x[1] < 0]), enumerate(input))
))

import re
s = re.sub(r'([\[ ]0[\],])+', ' ', input3)
s = s.replace(',  ', '], [')
if s[-1:] != ']':
    s = s[:-2] + ']'
s = '[' + s[2:]
s = re.sub(r' [0-9]+,', '', s)

output = list(eval(s))
print(output)  # [[3, 5], [9, 12], [16, 18]]