【问题标题】:How to sort all combinations in python?如何对python中的所有组合进行排序?
【发布时间】:2016-11-26 07:04:05
【问题描述】:

我有K=2N=3,我生成的所有组合如下:

list(itertools.product(range(1, N+1), repeat=K))

我明白了

[(1, 1), 
 (1, 2),
 (1, 3), 
 (2, 1), 
 (2, 2), 
 (2, 3), 
 (3, 1), 
 (3, 2), 
 (3, 3)]

我需要对这些组合进行排序得到

[(1, 1), 
 (2, 2),
 (3, 3),
 (1, 2),
 (1, 3), 
 (2, 1), 
 (2, 3), 
 (3, 1), 
 (3, 2)]

对于一般的KN,我该怎么做?

这就像拥有N 箱和K 物品,我想生成所有可能的物品分配到箱,但从

  • 所有项目分配到 bin 1,然后是 bin 2,等等。
  • K-1 件物品分配到箱 1,一件物品分配到箱 2,等等。
  • ...

所以在示例中,(1, 1) 表示所有项目都在 bin 1 中,(2, 2) 表示所有项目都在 bin 2 中,以此类推。(1, 2) 表示项目 1 在 bin 1 中,项目 2 在 bin 中2等。

【问题讨论】:

    标签: python combinations


    【解决方案1】:

    它已经几乎按照你想要的方式生成了,所以你可以利用 python 的稳定排序:

    >>> L = list(itertools.product(range(1, N+1), repeat=K))
    >>> L.sort(key=lambda t: len(set(t)))
    >>> L
    [(1, 1), (2, 2), (3, 3), (1, 2), (1, 3), (2, 1), (2, 3), (3, 1), (3, 2)]
    

    这只是将具有最相等值的元组推向前面。它应该推广到与您描述的方式一致的更高维度。

    【讨论】:

    • 我不明白这是如何工作的。 len(set(t)) 总是返回 2,不是吗?你能解释一下发生了什么以及你所说的“稳定”是什么意思吗?
    • @freebie 至于 lambda 函数,len(set(t)) 将为 set((1,1)) 返回 1,为 set((1,2)) 返回 2,等等。这是因为在集合中,我们不会多次拥有相同的元素(除非它是一个多重集)。所以,事实上,set((1,1))={1} 在 python 中。
    • @Riebuoz 啊,是的,我明白了。所以排序是“稳定的”意味着如果元素是等价的,它们将保持在原来的位置?否则解决它会更复杂吗?
    • 是的。你也可以在这里看到解释stackoverflow.com/a/1517824/3745674。我不知道复杂性,但我认为,在最坏的情况下,这并不重要。
    • 啊,所以从那篇文章中可以看出,好处是堆叠排序。因此,如果他们一开始是无序的 (random.shuffle) 你可以L.sort() 然后L.sort(key=lambda t: len(set(t)))
    【解决方案2】:

    你可以这样做:

    import itertools
    K = 2
    N = 3
    a = list(itertools.product(range(1, N+1), repeat=K))
    a_sorted = sorted(a, key=lambda t: -(t[0] == t[1]))
    

    lambda 函数告诉sorted 将相同数量的元组放在开头。我们还需要对数值进行排序,但由于这是sorted的默认行为,我们不需要手动添加。

    【讨论】:

    • 对。你的lambda t: len(set(t)) 更好。
    • 为什么是-(t[0] == t[1]) 而不是t[0] != t[1]
    • 确实t[0] != t[1] 更好。当我想出答案时,我考虑的是数字因素,而不是简单的布尔值。
    猜你喜欢
    • 2016-07-12
    • 1970-01-01
    • 2018-07-04
    • 1970-01-01
    • 2017-08-14
    • 1970-01-01
    • 1970-01-01
    • 2016-02-26
    • 1970-01-01
    相关资源
    最近更新 更多