查找数字与数字之间的可自定义距离

Cur*_*tLH 5 python int list-comprehension list

我有一个整数的排序列表,我发现想要查找此列表中的数字运行.我在寻找增加1的数字运行时看到了很多例子,但我也想查找数字运行,其中数字之间的差异是可自定义的.

例如,假设我有以下数字列表:

nums = [1, 2, 3, 6, 7, 8, 10, 12, 14, 18, 25, 28, 31, 39]
Run Code Online (Sandbox Code Playgroud)

使用此处的示例,我可以找到以下数字运行:

[[1, 2, 3], [6, 7, 8], [10], [12], [14], [18], [25], [28], [31], [39]]
Run Code Online (Sandbox Code Playgroud)

但是,我想查找数字运行,其中两个数字之间的差异可能不仅仅是1.例如,我希望所有数字运行的距离小于或等于2.

[[1, 2, 3], [6, 7, 8, 10, 12, 14], [18], [25], [28], [31], [39]] 
Run Code Online (Sandbox Code Playgroud)

或者我想要所有的数字运行距离小于或等于3.

[[1, 2, 3, 6, 7, 8, 10, 12, 14], [18], [25, 28, 31], [39]]
Run Code Online (Sandbox Code Playgroud)

这是我现在正在使用的函数,以获得距离为1的数字运行.

def runs(seq, n):
    result = []
    for s in seq:
        if not result or s != result[-1][-1] + n:
            # Start a new run if we can't continue the previous one.
            result.append([])
        result[-1].append(s)
    return result
Run Code Online (Sandbox Code Playgroud)

使用当前函数,如果我设置n=1,那么我找到所有连续的数字序列.如果我设置n=2,那么我只找到[8, 10, 12, 14].如何修改此函数以查找小于或等于的数字运行n?

我希望能够这样做:

runs(num, 2)
[[1, 2, 3], [6, 7, 8, 10, 12, 14], [18], [25], [28], [31], [39]] 
Run Code Online (Sandbox Code Playgroud)

cs9*_*s95 7

迭代分组for

我只是用这个修复你的代码.为了简化问题,你可以初始化result用seq[0].

def runs(seq, n):
    result = [[seq[0]]]
    for s in seq[1:]:
        if s - result[-1][-1] > n:  # Keep it simple. Compare the delta.
            result.append([])
        result[-1].append(s)

    return result
Run Code Online (Sandbox Code Playgroud)

>>> runs(nums, 1)
[[1, 2, 3], [6, 7, 8], [10], [12], [14], [18], [25], [28], [31], [39]]
>>> runs(nums, 2)
[[1, 2, 3], [6, 7, 8, 10, 12, 14], [18], [25], [28], [31], [39]]
Run Code Online (Sandbox Code Playgroud)

pandas.GroupBy

如果你想得到花哨,你可以使用groupby成语,用熊猫轻松.

import pandas as pd

def runs2(seq, n):
    s = pd.Series(seq)
    return s.groupby(s.diff().gt(n).cumsum()).apply(pd.Series.tolist).tolist()
Run Code Online (Sandbox Code Playgroud)

>>> runs2(nums, 3)
[[1, 2, 3, 6, 7, 8, 10, 12, 14], [18], [25, 28, 31], [39]]
Run Code Online (Sandbox Code Playgroud)

这里有两个基本要素:石斑鱼(你正在分组的谓词)和聚合函数(你将对每个组应用的函数)

石斑鱼被s.diff().gt(n).cumsum()分解计算三件事:

  1. 在逐元素差seq使用diff
  2. 一个布尔掩码,指示diff是否大于 n
  3. 执行累计和(或计数)以确定组

此操作的输出是

s.diff().gt(n).cumsum()

0     0
1     0
2     0
3     1
4     1
5     1
6     1
7     1
8     1
9     2
10    3
11    4
12    5
13    6
dtype: int64
Run Code Online (Sandbox Code Playgroud)

agg函数是pd.Series.tolist,并将任何系列转换为列表.这就是我们需要的,一个嵌套列表.