如何在Python中根据与其他元素的距离对列表中的元素进行分组?

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

我有一个号码列表。我想将彼此距离在 4 范围内的数字分组。例如,如果我有一个列表

[1,34,45,34,66,35,14,3,5,12,4,62,31,4,13,12]
。我想把时尚元素分组
"1 3 5 4 4 ;34 34 35 31 ;45 ;66 62 ;14 12 13 12 ;"
。说清楚一点:

Input >> [1,34,45,34,66,35,14,3,5,12,4,62,31,4,13,12]

Output >> 1 3 5 4 4 ;34 34 35 31 ;45 ;66 62 ;14 12 13 12 ;

为此,我编写了以下代码:

arr = [1,34,45,34,66,35,14,3,5,12,4,62,31,4,13,12]
bucket = ''
while arr != []:
    element = arr.pop(0)
    bucket += (str(element) + ' ')
    for term in arr:
        if abs(element-term)<= 4:
            bucket += (str(term) + ' ')
            arr.remove(term)
            print(bucket)
            print(arr)
    else:
        bucket += ';'
print(arr)
print(bucket)

我预计最终输出如下:

1 3 5 4 4 ;34 34 35 31 ;45 ;66 62 ;14 12 13 12 ;

但是我最终得到的输出是:

1 3 4 4 ;34 34 35 31 ;45 ;66 62 ;14 12 12 ;5 ;13 ;

此处元素“5”应该位于第一个存储桶中,但在输出中它不在应有的存储桶中。同样,“13”也不合适

The complete output

任何有助于识别代码中问题的帮助将不胜感激。

python python-3.x
5个回答
1
投票

问题是您没有考虑删除这些术语之前的元素 就像当你删除 3 个术语时,它位于第 7 个位置(术语 = 6) arr = [34,45,34,66,35,14,5,12,4,62,31,4,13,12] ^5 成为第 7 位 但 term 不断增加,所以它跳过了 5 在退出 for 循环之前尝试使 term=term-1


0
投票

我相信这应该可以达到您想要的结果(尽管您仍然需要格式化输出):

def group_numbers(numbers, max_difference=4):
groups = []
for number in numbers:
    found_group = False
    for group in groups:
        for member in group:
            if abs(member - number) <= max_difference:
                group.append(number)
                found_group = True
                break

            # remove this if-block if a number should be added to multiple groups
            if found_group:
                break
    if not found_group:
        groups.append([number])
return groups


print(group_numbers([1,34,45,34,66,35,14,3,5,12,4,62,31,4,13,12]))

输出: [[1,3,5,4,4],[34,34,35,31],[45],[66,62],[14,12,13,12]]


0
投票

当您到达列表中的元素 5 和 13 时,4 范围内的其他元素已全部删除并放入存储桶中,这就是为什么您为剩余的两个元素获得新的存储桶。

也许最好使用存储桶列表来检查每个新元素是否在 4 到存储桶中其他元素的范围内,然后添加它。这样,您就可以避免原始列表中没有足够的元素。


0
投票

您在迭代列表时从列表中删除元素,这会导致一些奇怪的跳过行为。您可能会注意到,每次执行

arr.remove(term)
时,您都会跳过下一个元素。 5 被跳过,因为它前面有一个 3。同样,当 13 应该分配给第五组时,它被跳过了,因为它前面有一个 12(在它们之间的 4,62,31,4 已经被删除之后)。

这里有一些解释:在迭代时从列表中删除项目时出现奇怪的结果[重复],这里:如何在迭代时从列表中删除项目?.


0
投票

只需更正@phil 的答案即可。 在示例中添加了 38 和 70。

def group_numbers(numbers, max_difference=4):
    groups = []
    for number in numbers:
        found_group = False
        for group in groups:
            all_ok = True
            for member in group:
                if abs(member - number) > max_difference:
                    all_ok = False
                    break
            if all_ok:
                group.append(number)
                found_group = True
        if not found_group:
            groups.append([number])
    return groups


print(group_numbers([1,34,45,34,66,35,14,3,5,12,4,62,31,4,13,12, 38, 70]))

输出:[[1, 3, 5, 4, 4], [34, 34, 35, 31], [45], [66, 62], [14, 12, 13, 12], [38], [70]]

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