简体   繁体   English

拆分整数列表,使它们产生具有最小差异的子列表

[英]Splitting list of integers such that they result in sublists with minimum difference

How would I split list of integers such that I would have them in sublists with minimum difference?我将如何拆分整数列表,以便将它们放在具有最小差异的子列表中?

For example例如

[4,1,5,3] --> [[1], [3,4,5]], length 2 [4,1,5,3] --> [[1], [3,4,5]], 长度 2

[4,2,1,3] --> [[1,2,3,4]], length 1 [4,2,1,3] --> [[1,2,3,4]],长度为1

[5,2,7,6,3,9] --> [[2,3], [5,6], [9]], length 3 [5,2,7,6,3,9] --> [[2,3], [5,6], [9]], 长度 3

[1,2,3,4,5,6,8,9,10] --> [[1,2,3,4,5,6], [8,9,10]], length 2. [1,2,3,4,5,6,8,9,10] --> [[1,2,3,4,5,6], [8,9,10]],长度为2。

Current approach is目前的做法是

def split(l): 
    res = [] 
    n = len(l) 
    l.sort() 
    # If the list is just consecutive integers return 1
    if l == list(range(min(l), max(l)+1)): 
        return 1  
    for l0, l1 in zip(l, l[1:]): 
        if abs(l0 - l1) <= 1: 
           res.append([l0, l1]) 
    return len(res)

this works for the first three cases well, but the last one fails... I think the problem is that in the loop I'm just conditioning by the difference of the two consecutive integers...这适用于前三种情况,但最后一种失败了......我认为问题是在循环中我只是通过两个连续整数的差异来调节......

If you are allowed to use external packages more_itertools have split_when method which can what you want:如果您被允许使用外部包, more_itertoolssplit_when方法可以满足您的需求:

import more_itertools
lst = [1,2,3,4,5,6,8,9,10]
lst.sort()
splitted = list(more_itertools.split_when(lst, lambda x, y: abs(x-y) > 1))
print(splitted)

Output:输出:

[[1, 2, 3, 4, 5, 6], [8, 9, 10]]

I would just check if the difference between 2 numbers is bigger than 1:我只想检查两个数字之间的差异是否大于 1:

def mySplit(lst):
    res = []

    lst.sort()
    subList = [lst[0]]
    for i in range(1, len(lst)):
        prev, cur = lst[i-1], lst[i]
        if cur - prev > 1:
            res.append(subList)
            subList = []
        subList.append(cur)
 
    res.append(subList)
    return res


tests = ([4,1,5,3], [4,2,1,3], [5,2,7,6,3,9], [1,2,3,4,5,6,8,9,10,13])
for test in tests:
    print(mySplit(test))

Out:出去:

[[1], [3, 4, 5]]
[[1, 2, 3, 4]]
[[2, 3], [5, 6, 7], [9]]
[[1, 2, 3, 4, 5, 6], [8, 9, 10], [13]]

Very fast-running and short solution using numpy :使用numpy快速运行和简短的解决方案:
(once install numpy using python -m pip install numpy ). (一旦使用python -m pip install numpy )。

Try it online!在线试试吧!

import numpy as np

for l in [
    [4,1,5,3],
    [4,2,1,3],
    [5,2,7,6,3,9],
    [1,2,3,4,5,6,8,9,10],
]:
    a = np.sort(l)
    res = np.split(a, np.flatnonzero(np.abs(np.diff(a)) > 1) + 1)
    
    print('input', l, 'sorted', a, '\n', 'result', res)

Outputs:输出:

input [4, 1, 5, 3] sorted [1 3 4 5]
 result [array([1]), array([3, 4, 5])]
input [4, 2, 1, 3] sorted [1 2 3 4]
 result [array([1, 2, 3, 4])]
input [5, 2, 7, 6, 3, 9] sorted [2 3 5 6 7 9]
 result [array([2, 3]), array([5, 6, 7]), array([9])]
input [1, 2, 3, 4, 5, 6, 8, 9, 10] sorted [ 1  2  3  4  5  6  8  9 10]
 result [array([1, 2, 3, 4, 5, 6]), array([ 8,  9, 10])]

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM