通过保持最小值和最大值对列表进行等距切片

2024-09-19 23:45:58 发布

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

我需要从线性整数列表(不能从0开始)中获得“相等”步长切片,但需要满足以下要求:

  • 必须始终显示最后一个值(最大值)
  • 间隔不得低于步长(最重要的是,从下一个值到最后一个值之间)
  • 考虑到上面的点,一些间隔可能高于步骤,并且这些间隔必须在结果列表之间平均放置
  • 只能使用标准库函数(无numpy)

一些例子:

  • 使用来自range(10)和步骤2的列表,结果应为以下之一:

    [0, 2, 5, 7, 9]
    [0, 2, 4, 7, 9]

  • 使用range(21)和步骤3:

    [0, 3, 7, 10, 14, 17, 20]

  • 使用range(1, 22)和步骤3:

    [1, 4, 8, 11, 15, 18, 21]

现在我有类似的东西,显然不能正常工作:

def getSlices(l, s):
    skipCount = (len(l) - 1) % s
    divCount = int(len(l) / (skipCount + 1))

    o = []
    for delta, skip in enumerate(range(skipCount + 1)):
        o.extend(l[skip * divCount + delta:(skip + 1) * divCount + delta:s])
    return o

>>> getSlices(list(range(21)), 3)
[0, 3, 6, 8, 11, 14, 16, 19]

我知道我可以循环遍历所有值,通过关联enumerate索引和步骤跳过,并在到达列表的新“部分”时添加“增量”,但这似乎不是最有效的解决方案


Tags: 列表间隔len步骤切片range线性整数
1条回答
网友
1楼 · 发布于 2024-09-19 23:45:58

我想这可能是你想要的。希望能有帮助

def getSlices(l, step):

    init = l[0]
    last = l[-1]  # exclude last element (remove as you want)

    slices = (last-init) // step + 1
    mod = (last-init) % step
    even = mod // 2
    mid = slices // 2 - 1
    even_start = mid - even
    even_end = mid + mod - even

    final = []

    val = init
    for i in range(slices):
        final.append(val)
        val += step

        # Distribute mod unitary in the middle
        if slices-1 >= mod:
            if mod > 0 and (even_start <= i <= even_end):
                val += 1
                # In case is the middle don't change it
                if i == mid:
                    val += - 1

        # Distribute mod evenly all across the slices
        else:
            val += mod // (slices-1)
            # In case a there is mod left, place it just in the middle
            if i == mid:
                val += mod % (slices-1)

    return final

# Examples:
#
# getSlices(list(range(10)), 2)
# [0, 2, 4, 7, 9]
#
# getSlices(list(range(21)), 3)
# [0, 3, 7, 10, 14, 17, 20]
#
# getSlices(list(range(1, 22)), 3)
# [1, 4, 8, 11, 15, 18, 21]
#
# getSlices(list(range(36)), 10)
# [0, 11, 24, 35]

相关问题 更多 >