我为此感到苦恼,因为我确定十几个for循环不是解决此问题的方法:
有一个排序的数字列表,例如
numbers = [123, 124, 128, 160, 167, 213, 215, 230, 245, 255, 257, 400, 401, 402, 430]
并且我想创建一个包含数字列表的字典,其中数字的差(紧随其后)不超过15。因此输出如下:
clusters = { 1 : [123, 124, 128], 2 : [160, 167], 3 : [213, 215, 230, 245, 255, 257], 4 : [400, 401, 402], 5 : [430] }
我当前的解决方案有点难看(我必须在末尾删除重复项……),我确信它可以用pythonic方式完成。
这就是我现在要做的:
clusters = {} dIndex = 0 for i in range(len(numbers)-1) : if numbers[i+1] - numbers[i] <= 15 : if not clusters.has_key(dIndex) : clusters[dIndex] = [] clusters[dIndex].append(numbers[i]) clusters[dIndex].append(numbers[i+1]) else : dIndex += 1
如果您的列表很小,这不是绝对必要的,但是我可能会以“流处理”的方式进行处理:定义一个生成器,该生成器使您的输入可迭代,并产生分组为元素组的元素,这些元素的行距小于等于15。您可以使用它轻松地生成字典。
def grouper(iterable): prev = None group = [] for item in iterable: if not prev or item - prev <= 15: group.append(item) else: yield group group = [item] prev = item if group: yield group numbers = [123, 124, 128, 160, 167, 213, 215, 230, 245, 255, 257, 400, 401, 402, 430] dict(enumerate(grouper(numbers), 1))
印刷品:
{1: [123, 124, 128], 2: [160, 167], 3: [213, 215, 230, 245, 255, 257], 4: [400, 401, 402], 5: [430]}
另外,您甚至可以将跑步次数分组为可能无限的列表(当然,只要对它们进行排序即可)。您也可以将索引生成部分enumerate作为较小的增强而粘贴到生成器本身中(而不是使用)。
enumerate