根据连续值之间的差异在子列表中拆分列表

时间:2018-08-24 13:10:30

标签: python

我有一个包含值的列表,每个值至少具有一个(但经常是多个)连续值(以.033为增量):

l = [26.051, 26.084, 26.117, 26.15, 26.183, 31.146, 31.183, 34.477, 34.51, 34.543]

我想将此列表拆分为多个子列表,在这些子列表中,相差.033的连续项将被合并,并且当差异较大时,将创建一个新的子列表:

l = [ [26.051, 26.084, 26.117, 26.15, 26.183], [31.146, 31.183], [34.477, 34.51, 34.543] ] 

4 个答案:

答案 0 :(得分:4)

跟踪您看到的最后一个元素,或者将当前项目追加到最后一个子列表,或者如果差异大于允许的增量,则创建一个新的子列表。

res, last = [[]], None
for x in l:
    if last is None or abs(last - x) <= 0.033:
        res[-1].append(x)
    else:
        res.append([x])
    last = x

但是请注意,0.033的值实际上不会返回您想要的结果,因为由于浮点舍入,有些差异要大得多(0.037)或稍多一些。相反,您可能希望使用稍微更大一些的值,例如,使用0.035会给您[[26.051, 26.084, 26.117, 26.15, 26.183], [31.146], [31.183], [34.477, 34.51, 34.543]]

答案 1 :(得分:1)

一个人可以使用临时列表和for循环来获得所需的结果:

l = [26.051, 26.084, 26.117, 26.15, 26.183, 31.146, 31.183, 34.477, 34.51, 34.543]
outlist = []
templist = [l.pop(0)]
while len(l)>0:
    x = l.pop(0)
    if x - templist[-1] > 0.04:
        outlist.append(templist)
        templist = [x]
    else: 
        templist.append(x)
outlist.append(templist)
print(outlist)

输出:

[[26.051, 26.084, 26.117, 26.15, 26.183], [31.146, 31.183], [34.477, 34.51, 34.543]]

答案 2 :(得分:1)

如果您是itertools的粉丝,则可以使用itertools.groupby()

from itertools import groupby

l = [26.051, 26.084, 26.117, 26.15, 26.183, 31.146, 31.183, 34.477, 34.51, 34.543]

def keyfunc(x):
    return (x[0] > 0 and round(l[x[0]] - l[x[0]-1], 3) == 0.033 or
            x[0] < len(l) - 1 and round(l[x[0]+1] - l[x[0]], 3) == 0.033)

print([[x[1] for x in g] for k, g in groupby(enumerate(l), key=keyfunc)])

输出:

[[26.051, 26.084, 26.117, 26.15, 26.183], [31.146, 31.183], [34.477, 34.51, 34.543]]

就逻辑而言,键函数针对具有相邻0.033和没有差异的数字返回不同的键。然后groupby()对其进行相应分组。

答案 3 :(得分:1)

我的方法涉及遍历成对的连续数字并检查它们之间的差距,就像其他人一样。此处的区别在于使用iter()从一个列表创建两个可迭代对象。

# Given:
l = [26.051, 26.084, 26.117, 26.15, 26.183, 31.146, 31.183, 34.477, 34.51, 34.543]
gap = 0.033

# Make two iterables (think: virtual lists) from one list
previous_sequence, current_sequence = iter(l), iter(l)

# Initialize the groups while advancing current_sequence by 1
# element at the same time
groups = [[next(current_sequence)]]

# Iterate through pairs of numbers
for previous, current in zip(previous_sequence, current_sequence):
    if abs(previous - current) > gap:
        # Large gap, we create a new empty sublist
        groups.append([])

    # Keep appending to the last sublist
    groups[-1].append(current)

print(groups)

一些笔记

  • 我的解决方案看起来很长,但是如果您减去所有注释,空白喜欢和最后一个打印语句,则只有6行
  • 这是有效的,因为我实际上没有重复该列表
  • 一个空列表(空l)将生成一个StopIteration异常,因此请确保列表不为空