简体   繁体   English

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

[英]How to group elements of a list in python based on their distance from other elements?

I have a list of numbers.我有一个数字列表。 I want to group the numbers which lie within a distance of 4 from each other.我想将彼此相距4以内的数字分组。 For example if I have a list [1,34,45,34,66,35,14,3,5,12,4,62,31,4,13,12] .例如,如果我有一个列表[1,34,45,34,66,35,14,3,5,12,4,62,31,4,13,12] I want to group the elements in the fashion "1 3 5 4 4 ;34 34 35 31 ;45 ;66 62 ;14 12 13 12 ;"我想将时尚元素分组为"1 3 5 4 4 ;34 34 35 31 ;45 ;66 62 ;14 12 13 12 ;" .To make it clear: . 说清楚:

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 ;

For this, I have written the following code:为此,我编写了以下代码:

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)

I expected the final output to be as follows:我预计最终输出如下:

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

But what I got in the final output was:但我在最终输出中得到的是:

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

here the element '5' should have been in the first bucket but in the output it is not in the bucket where it's supposed to be.这里的元素 '5' 应该在第一个桶中,但在输出中它不在它应该在的桶中。 Similarly '13' is out of its place同样,“13”也不合适

完整的输出

Any help in identifying the problem in the code will be greatly appreciated.任何帮助识别代码中的问题将不胜感激。

问题是您没有考虑在这些术语之前删除元素,例如当您删除 3 term 时位于第 7 个位置 (term=6) arr = [34,45,34,66,35,14,5,12, 4,62,31,4,13,12] ^5 变为第 7 位,但 term 继续递增,因此它跳过 5 尝试在退出 for 循环之前使 term=term-1

By the time you come to the elements 5 and 13 in your list, the other elements that are in range of 4 have all been removed already and put into buckets, that's why you get new buckets for the two remaining.当您到达列表中的元素 5 和 13 时,范围为 4 的其他元素已经全部删除并放入桶中,这就是为什么您为剩余的两个元素获得新桶的原因。

Maybe it would be better to use lists for the buckets to check for each new element whether it is in the range of 4 to every other element in the bucket and then adding it.也许最好使用存储桶的列表来检查每个新元素是否在 4 到存储桶中的每个其他元素的范围内,然后添加它。 That way, you avoid having not enough elements in your original list.这样,您就可以避免原始列表中没有足够的元素。

You're removing elements from the list while you're iterating it, which leads to some odd skipping behavior.您在迭代列表时从列表中删除元素,这会导致一些奇怪的跳过行为。 You may notice that each time you're doing arr.remove(term) , you're skipping the next element.您可能会注意到,每次执行arr.remove(term) ,都会跳过下一个元素。 The 5 got skipped because there was a 3 right before it. 5 被跳过了,因为在它之前有一个 3。 Similarly, at the point when 13 should be assigned to the 5th group, it got skipped because it was preceded by a 12 (after the 4,62,31,4 between them had already been removed).同样,在应该将 13 分配给第 5 组时,它被跳过了,因为它前面是 12(在它们之间的 4、62、31、4 已经被删除之后)。

There is some explanation here: Strange result when removing item from a list while iterating over it [duplicate] and here: How to remove items from a list while iterating?这里有一些解释: 在迭代时从列表中删除项目时出现奇怪的结果 [重复]和这里: 如何在迭代时从列表中删除项目? . .

I believe this should achieve your desired result (although you would still need to format the output):我相信这应该可以达到您想要的结果(尽管您仍然需要格式化输出):

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

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

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

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