根据值获取列表的列表索引范围

2024-09-29 06:34:03 发布

您现在位置:Python中文网/ 问答频道 /正文

我有一个列表,如下所示:

Values = [0,0,1,1,1,1,1,2,2,2,3,3,3,3,3,3,4,4,4,5,5,5,5]

我想得到的索引范围取决于值。例如,对于我想要得到的值“0”:

IndexRange0 = range(0,2) = [0,1]    
#the element "0" is taking the positions 0 and 1 of the list "Values"

对于值“1”,我想得到:

IndexRange1 = range(2,7) = [2,3,4,5,6]

等等。 最后,我想得到一个“这些范围的列表”,比如说:

FinalOutput = [IndexRange0, IndexRange1, .... IndexRange5]

我不知道如何做到这一点,而不使用昂贵的建设与循环和糟糕的工作周围。你知道吗?你知道吗

注意:数字将一直递增。范围的长度是变量(这次有2个“零”,下次可能是5等),但其顺序总是一个接一个地增加(会有一组0,然后是一组1,然后是一组2等,直到一个非固定整数n)。事先谢谢你的帮助。你知道吗


Tags: andofthe列表israngeelementlist
3条回答

由于值总是增加一个,因此这里有另一种方法可以做到这一点,而不必显式计算每个值的出现次数:

>>> Values = [0,0,1,1,1,1,1,2,2,2,3,3,3,3,3,3,4,4,4,5,5,5,5]
>>> starts = [Values.index(i) for i in range(Values[-1] + 1)] + [len(Values)]
>>> print starts
[0, 2, 7, 10, 16, 19, 23]
>>> ranges = [range(starts[i], starts[i + 1]) for i in range(len(starts) - 1)]
>>> for r in ranges:
...    print r
... 
[0, 1]
[2, 3, 4, 5, 6]
[7, 8, 9]
[10, 11, 12, 13, 14, 15]
[16, 17, 18]
[19, 20, 21, 22]

使用itertools.groupby

from itertools import groupby
from operator import itemgetter
Values = [0,0,1,1,1,1,1,2,2,2,3,3,3,3,3,3,4,4,4,5,5,5,5]
output = []
for k, g in groupby(enumerate(Values), key=itemgetter(1)):
    start = next(g)[0]
    for end, _ in g: pass
    output.append((start, end+1))
print output 

输出:

[(0, 2), (2, 7), (7, 10), (10, 16), (16, 19), (19, 23)]

我建议bisectitertools.takewhile,这取决于您计划如何使用它。你知道吗

对分:

import bisect

def index_range(n, lst):
    return (bisect.bisect_left(lst, n), bisect.bisect_right(lst, n))

def final_output(rng, lst):
    return [index_range(n, lst) for n in rng]

values = [0,0,1,1,1,1,1,2,2,2,3,3,3,3,3,3,4,4,4,5,5,5,5]
print(final_output(range(0,6), values))

给予

[(0, 2), (2, 7), (7, 10), (10, 16), (16, 19), (19, 23)]

相关问题 更多 >