【问题标题】:How can I make my output group all similar numbers into a specific number of groups?如何使我的输出将所有相似的数字组合成特定数量的组?
【发布时间】:2021-11-08 05:08:55
【问题描述】:

所以我写了这段代码,目的是让代码将列表中的不同数字组合在一起,总共n: int

编辑如果你不明白代码的目的是什么,请查看 cmets,我已经解释过了。谢谢:)

def calcdifference(lst: list):
    for x in lst:
        return (x -= x)
print(calcdifference(lst=[4,5,6,4,3,2,3,4,5]))

def grouping(lst: list, n: int):
    if calcdifference(x) in list == max(calcdifference(x)):
        lst.append(x)
print(grouping(lst=[4,5,6,4,3,2,3,4,5]))

n: int 表示一个列表中允许的组数,因此如果 n 为 3,则这些数将分组为 (x,...), (x,..) (x,.. .) 如果 n = 2,则数字将分组为 (x,..),(x,...)。

但是,我的代码在 n 个元素的列表中打印出所有可能的组合。但它不会将数字组合在一起。所以我想要的是:例如,如果输入是

[10,12,45,47,91,98,99]

如果 n = 2,则输出为

[10,12,45,47] [91,98,99]

如果 n = 3,则输出为

[10,12] [45,47] [91,98,99]

我应该对我的代码进行哪些更改?

注意:请不要使用内置函数或导入,因为我希望尽可能少使用内置函数

重要提示:代码应该能够为所提供的每个列表打印n >= len(lst) 组合

【问题讨论】:

  • 我想我几个小时前看到了这个问题,我想n 的问题在这里有点解决了。但是,背后的逻辑是什么?为什么不呢,例如当n=2[10,12,45] [47,91,98,99] 不是预期的时候?当n 大于len(lst) 时会发生什么?
  • @j1-lee 是的,我尝试使用不同的方法获得答案,但也失败了,所以我又问了一遍,哈哈。 n 不能大于 len(list),因为列表中的最大分组数等于 len(list)。例如,如果列表中有 5 个元素,则最大分组数为 5。
  • @j1-lee 所以逻辑是对于输入的列表,我们必须将列表中的每个相似数字分开并将它们组合在一起。我尝试使用 calcdifference 来查找列表中每个数字之间的差异。在差异最大的地方,我计划将列表分成 n 组。如果它说 n = 1,那么我会寻找差异最大的组合并将其分开。如果 n = 2,我会在列表中查找 2 个最大的差异并将它们分开。如果 n = 3,那么我会寻找前 3 个最大的差异并将其分开
  • 另见:集群。也许像 k-means 之类的东西。
  • 这能回答你的问题吗? 1D Number Array Clustering

标签: python list tuples grouping


【解决方案1】:

您可以尝试以下方法:

def grouping(lst, n):
    diff = enumerate((abs(x - y) for x, y in zip(lst, lst[1:])), start=1)
    cut = sorted(x[0] for x in sorted(diff, reverse=True, key=lambda x: x[1])[:n-1])
    cut = [0, *cut, len(lst)] # add 0 and last index
    return [lst[i:j] for i, j in zip(cut, cut[1:])] # return slices

lst = [10,12,45,47,91,98,99]
print(grouping(lst, 2))
print(grouping(lst, 3))
print(grouping(lst, 4))

输出:

[[10, 12, 45, 47], [91, 98, 99]]
[[10, 12], [45, 47], [91, 98, 99]]
[[10, 12], [45, 47], [91], [98, 99]]

诚然,它相当复杂,而且可能不那么 Pythonic。可能有更有效的方法。无论如何,一些解释如下......

在第一行中,diff 是一个包含元组 (i, d) 的(某种)列表,因此 lsti-1th 项和 ith 项之间的差异为 d

第二行更复杂。首先sorted(diff, reverse=True, key=lambda x: x[1])根据第二个元素对这些元组进行排序,即代表最高跳跃的元组在前。

然后sorted(...)[:n-1] 选择前 n-1 个元组。这些将是要使用的 n-1 个削减。

生成器理解(x[0] for x in ...) 只选择每个元组的第一项;即,我们不再需要差异。

然后sorted(...) 将再次对这些剪切位置进行排序,这将使后续行工作。


如果你因为某种原因不愿意使用lambda(实际上operator.itemgetter(1)lambda x: x[1]好),你可以为此定制一个函数。

def get_1st(x):
    return x[1]

def grouping(lst, n):
    diff = enumerate((abs(x - y) for x, y in zip(lst, lst[1:])), start=1)
    cut = sorted(x[0] for x in sorted(diff, reverse=True, key=get_1st)[:n-1])
    cut = [0, *cut, len(lst)] # add 0 and last index
    return [lst[i:j] for i, j in zip(cut, cut[1:])] # return slices

【讨论】:

  • 感谢您的回复。但是,是否可以不使用 key=lambda.. 就像其他一切都很棒。我理解除了 key=lambda 之外的所有内容,你知道这对我很有帮助,写一个我自己能理解的代码。
猜你喜欢
  • 2021-09-08
  • 1970-01-01
  • 1970-01-01
  • 2021-01-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-07-15
相关资源
最近更新 更多