通过保持最小和最大,对列表进行等步切分。

问题描述 投票:0回答:1

我需要从一个线性整数列表(不能从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) 和第三步。

    [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 索引和步长,并在达到列表的新 "部分 "时立即添加一个 "delta",但这似乎不是性能最好的解决方案。

python slice
1个回答
1
投票

我想这可以按照你的要求去做。希望它能帮助你。

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]

© www.soinside.com 2019 - 2024. All rights reserved.