python - 在列表中查找递增数字组

标签 python list tuples python-itertools iterable

目标是在给定整数列表的情况下找到递增/单调数组。结果组中的每个项目都必须比前一个项目增加 +1

给定一个输入:

x = [7, 8, 9, 10, 6, 0, 1, 2, 3, 4, 5]

我需要找到数量递增的组并实现:

increasing_numbers = [(7,8,9,10), (0,1,2,3,4,5)]

最终还有越来越多的数字:

len(list(chain(*increasing_numbers)))

还有组的长度:

increasing_num_groups_length = [len(i) for i in increasing_numbers]

我尝试了以下方法来获取递增的数字:

>>> from itertools import tee, chain
>>> def pairwise(iterable): 
...     a, b = tee(iterable)
...     next(b, None)
...     return zip(a, b)
... 
>>> x = [8, 9, 10, 11, 7, 1, 2, 3, 4, 5, 6]
>>> set(list(chain(*[(i,j) for i,j in pairwise(x) if j-1==i])))
set([1, 2, 3, 4, 5, 6, 8, 9, 10, 11])
>>> len(set(list(chain(*[(i,j) for i,j in pairwise(x) if j-1==i]))))
10

但是我无法保持顺序和递增的组数。

如何实现 increasing_numbers 组整数元组以及 increasing_num_groups_length

另外,是否有此类/类似问题的名称?


已编辑

我想出了这个解决方案,但它非常冗长,我相信有一种更简单的方法可以实现 increasing_numbers 输出:

>>> from itertools import tee, chain
>>> def pairwise(iterable): 
...     a, b = tee(iterable)
...     next(b, None)
...     return zip(a, b)
... 
>>> x = [8, 9, 10, 11, 7, 1, 2, 3, 4, 5, 6]
>>> boundary =  iter([0] + [i+1 for i, (j,k) in enumerate(pairwise(x)) if j+1!=k] + [len(x)])
>>> [tuple(x[i:next(boundary)]) for i in boundary]
[(8, 9, 10, 11), (1, 2, 3, 4, 5, 6)]

是否有更 pythonic/更简洁的方法来做到这一点?


另一个输入/输出示例:

[在]:

[17, 17, 19, 20, 21, 22, 0, 1, 2, 2, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 14, 14, 28, 29, 30, 31, 32, 33, 34, 35, 36, 40]

[输出]:

[(19, 20, 21, 22), (0, 1, 2), (4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14), (28, 29, 30, 31, 32, 33, 34, 35, 36)]

最佳答案

编辑:

这是一个代码高尔夫解决方案(142 个字符):

def f(x):s=[0]+[i for i in range(1,len(x)) if x[i]!=x[i-1]+1]+[len(x)];return [x[j:k] for j,k in [s[i:i+2] for i in range(len(s)-1)] if k-j>1]

扩展版:

def igroups(x):
    s = [0] + [i for i in range(1, len(x)) if x[i] != x[i-1] + 1] + [len(x)]
    return [x[j:k] for j, k in [s[i:i+2] for i in range(len(s)-1)] if k - j > 1]

评论版本:

def igroups(x):
    # find the boundaries where numbers are not consecutive
    boundaries = [i for i in range(1, len(x)) if x[i] != x[i-1] + 1]
    # add the start and end boundaries
    boundaries = [0] + boundaries + [len(x)]
    # take the boundaries as pairwise slices
    slices = [boundaries[i:i + 2] for i in range(len(boundaries) - 1)]
    # extract all sequences with length greater than one
    return [x[start:end] for start, end in slices if end - start > 1]

原方案:

不确定这算作“pythonic”还是“不太冗长”:

def igroups(iterable):
    items = iter(iterable)
    a, b = None, next(items, None)
    result = [b]
    while b is not None:
        a, b = b, next(items, None)
        if b is not None and a + 1 == b:
            result.append(b)
        else:
            if len(result) > 1:
                yield tuple(result)
            result = [b]

print(list(igroups([])))
print(list(igroups([0, 0, 0])))
print(list(igroups([7, 8, 9, 10, 6, 0, 1, 2, 3, 4, 5])))
print(list(igroups([8, 9, 10, 11, 7, 1, 2, 3, 4, 5, 6])))
print(list(igroups([9, 1, 2, 3, 1, 1, 2, 3, 5])))

输出:

[]
[]
[(7, 8, 9, 10), (0, 1, 2, 3, 4, 5)]
[(8, 9, 10, 11), (1, 2, 3, 4, 5, 6)]
[(1, 2, 3), (1, 2, 3)]

关于python - 在列表中查找递增数字组,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/33402355/

相关文章:

python - 如何安装特定python版本的pip?

python - 将列表作为索引传递以在 n 维嵌套列表中赋值

python - 展平未知长度的元组

python - 列表中不同元组的元素组合

java - 如果存在特定键 Java 8 的值,则检查列表映射

同时交叉和添加列表元素的 Pythonistic 方法

python - 在 PyOpenSSL 中启动重新协商

python - 合并数据框/面板以允许导出到 *ONE* excel 表,而不是多个

python - 限制嵌入式Python的执行时间

list - LISP:按升序排列列表项