我有一个号码列表。我想将彼此距离在 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”也不合适
任何有助于识别代码中问题的帮助将不胜感激。
问题是您没有考虑删除这些术语之前的元素 就像当你删除 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
我相信这应该可以达到您想要的结果(尽管您仍然需要格式化输出):
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]]
当您到达列表中的元素 5 和 13 时,4 范围内的其他元素已全部删除并放入存储桶中,这就是为什么您为剩余的两个元素获得新的存储桶。
也许最好使用存储桶列表来检查每个新元素是否在 4 到存储桶中其他元素的范围内,然后添加它。这样,您就可以避免原始列表中没有足够的元素。
您在迭代列表时从列表中删除元素,这会导致一些奇怪的跳过行为。您可能会注意到,每次执行
arr.remove(term)
时,您都会跳过下一个元素。 5 被跳过,因为它前面有一个 3。同样,当 13 应该分配给第五组时,它被跳过了,因为它前面有一个 12(在它们之间的 4,62,31,4 已经被删除之后)。
这里有一些解释:在迭代时从列表中删除项目时出现奇怪的结果[重复],这里:如何在迭代时从列表中删除项目?.
只需更正@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]]