【问题标题】:How to group elements of a list that are within n of each other如何对彼此相距 n 的列表元素进行分组
【发布时间】:2020-03-02 12:01:03
【问题描述】:

我有两个列表:

list_1 = []
list_2 = [1.0, 3.0, 3.15, 1.03, 6.0, 7.0]

我想对这个列表进行排序并合并(在本例中)0.15 内的元素。

所以到此结束时,list_1 包含以下值:

[[1.0, 1.03],[3.0, 3.15]]

因为1.01.03 彼此相差在 0.15 以内,而3.03.15 也在彼此相差 0.15 以内。

这也可以不仅仅是对,所以例如如果我有3.16,那是在3.15的范围内,所以它会被添加到组中,即:

list_2 = [1.0, 3.0, 3.15, 1.03, 6.0, 7.0, 3.16]

输出:

[[1.0,1.03],[3.0,3.15,3.16]]

我该怎么做?

感谢您的帮助!

【问题讨论】:

    标签: python python-3.x list


    【解决方案1】:

    networkx 在这里太过分了。只需先对列表进行排序,然后在先前和当前之间的差异大于您的增量时迭代并生成一个块。

    >>> list_2 = [1.0, 3.0, 3.15, 1.03, 6.0, 7.0, 3.16]
    >>> list_2.sort()
    >>> delta = 0.15
    >>> list_1 = []
    >>> prev = -float('inf')
    >>> for x in list_2:
    ...     if x - prev > delta:
    ...         list_1.append([x])
    ...     else:
    ...         list_1[-1].append(x)
    ...     prev = x
    ...
    >>> list_1
    [[1.0, 1.03], [3.0, 3.15, 3.16], [6.0], [7.0]]
    >>> [x for x in list_1 if len(x) > 1]
    [[1.0, 1.03], [3.0, 3.15, 3.16]]
    

    【讨论】:

    • 您介意发布代码 sn-p 吗?我也很感谢您的回复
    • 添加了一个 sn-p。不确定您是否要修剪“单例”组...
    • 好电话!不需要连接组件,因为值是数字并且可以排序。
    • 是的,这正是我所需要的,再加上一点,非常感谢!
    【解决方案2】:

    要根据给定大小的间隙拆分列表,您可以使用 zip 将元素与其相邻元素进行比较,从而给出序列中中断的位置。然后再次压缩,将这些中断位置转换为原始数据的范围。

    data = [1, 2, 5, 6, 7, 9, 22, 24, 26, 29] 
    gap  = 2
    
    breaks  = [ i for i,(a,b) in enumerate(zip(data,data[1:]),1) if abs(a-b) > gap ]
    result  = [ data[s:e] for s,e in zip([0]+breaks,breaks+[len(data)]) ]
    
    print(result)
    [[1, 2], [5, 6, 7, 9], [22, 24, 26], [29]]
    

    请注意,这也适用于未排序的列表

    该技术可以概括为一个函数,该函数将在任何给定条件下拆分任何列表:

    def splitList(A,condition):
        breaks = [i for i,(a,b) in enumerate(zip(A,A[1:]),1) if condition(a,b)]
        return [A[s:e] for s,e in zip([0]+breaks,breaks+[len(A)])]
    
    
    data = [1, 2, 5, 6, 7, 9, 22, 24, 26, 29] 
    gap=2
    
    result = splitList(data,lambda a,b: abs(a-b)>gap)
    print(result)
    [[1, 2], [5, 6, 7, 9], [22, 24, 26], [29]]
    
    data   = [1, 2, 5, 6, 4,2,10,15,14,7,9,12]
    ascend = splitList(data,lambda a,b: a>b) # split ascending streaks
    print(ascend)
    [[1, 2, 5, 6], [4], [2, 10, 15], [14], [7, 9, 12]]
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2016-10-31
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2016-05-16
      相关资源
      最近更新 更多