有类似的question,但不是我要问的。
我们说我有一个零和一个零的列表:
# i.e. [1, 0, 0, 0, 1, 1, 1, 1, 0, 1]
sample = np.random.randint(0, 2, (10,)).tolist()
我试图找到相同值的子序列的索引,按其长度排序。所以在这里,我们将有以下子列表:
[1, 1, 1, 1]
[0, 0, 0]
[1]
[0]
[1]
所以他们的指数是[4, 1, 0, 8, 9]
。
我可以得到排序后的子序列:
sorted([list(l) for n, l in itertools.groupby(sample)], key=lambda l: -len(l))
然而,如果我重复后续步骤,我将无法立即找到索引(我将不得不使用另一个循环)。
我觉得有一种更直接和Pythonic的方式来做我以后的事情,就像前面问题的答案所表明的那样。这就是我正在寻找的。 p>
答案 0 :(得分:1)
您可以先使用enumerate(..)
创建索引和值的元组。接下来是groupby
,但是在元组的第二个元素上,最后将它们映射回第二个索引。像:
map(lambda x:x[0][0], # obtain the index of the first element
sorted([list(l) for _,l in itertools.groupby(enumerate(sample), # create tuples with their indices
key=lambda x:x[1])], # group in value, not on index
key=lambda l: -len(l)))
在控制台中运行(压缩命令)时,它会产生:
>>> map(lambda x:x[0][0],sorted([list(l) for _,l in itertools.groupby(enumerate(sample),key=lambda x:x[1])],key=lambda l: -len(l)))
[4, 1, 0, 8, 9]
<强> N.B。 1 :排序时,您可以使用
lambda l: -len(l)
(和key
),而不是将reverse=True
用作key = len
。 声明的,如:map(lambda x:x[0][0], sorted([list(l) for _,l in itertools.groupby(enumerate(sample), key=lambda x:x[1])], key=len, reverse=True))
<强> N.B。 2 :在python-3.x
map
中会生成迭代器,而不是列表。您可以通过调用list(..)
实现结果 结果。
答案 1 :(得分:0)
您可以使用带有生成器功能的groupby
sorted
函数来有效地执行此操作。
from itertools import groupby
from operator import itemgetter
data = [1, 0, 0, 0, 1, 1, 1, 1, 0, 1]
def gen(items):
for _, elements in groupby(enumerate(items)):
indexes, values = zip(*elements)
yield indexes[0], values
result = sorted(list(gen(data)), key=lambda x: len(x[1]), reverse=True)
打印结果产量:
[(4, (1, 1, 1, 1)), (1, (0, 0, 0)), (0, (1,)), (8, (0,)), (9, (1,))]