繁体   English   中英

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

[英]Split a list in sublists based on the difference between consecutive values

我有一个列表,其值为每个值至少有一个(但通常更多)连续值,其值为.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] ] 

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

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]]

可以使用临时列表和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]]

如果你是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()它们进行分组。

我的方法涉及通过成对的连续数字来检查它们之间的差距,就像其他人一样。 这里的区别在于使用iter()从一个列表创建两个iterables。

# 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异常,因此请确保列表不为空

暂无
暂无

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

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