【问题标题】:Get all pairwise combinations from a list从列表中获取所有成对组合
【发布时间】:2016-10-17 17:38:06
【问题描述】:

例如,如果输入列表是

[1, 2, 3, 4]

我希望输出是

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

如果可能,我想要一个比使用两个 for 循环的蛮力方法更好的解决方案。我该如何实现?

【问题讨论】:

  • n 个元素的集合有 2^n 对组合。所有解决方案都需要指数级的时间来生成所有组合;嵌套的 for 循环将使您处于最快解决方案的恒定因子内。除非你只是在寻找更紧凑的东西。
  • @lungj 我已经有一段时间没有正式学习数学了,但是你从哪里得到2^n 的数字?订购的对是 4! /(4 - 2)! (== 12) 和无序对是 4 选择 2 (== 6)
  • @brianpck 哎呀。你是对的。它是 O(n^2)。

标签: python list combinatorics


【解决方案1】:

虽然前面的答案会给你所有成对的排序,但示例预期结果似乎暗示你想要所有 unordered 对。

这可以通过itertools.combinations来完成:

>>> import itertools
>>> x = [1,2,3,4]
>>> list(itertools.combinations(x, 2))
[(1, 2), (1, 3), (1, 4), (2, 3), (2, 4), (3, 4)]

与其他结果比较:

>>> list(itertools.permutations(x, 2))
[(1, 2), (1, 3), (1, 4), (2, 1), (2, 3), (2, 4), (3, 1), (3, 2), (3, 4), (4, 1), (4, 2), (4, 3)]

【讨论】:

    【解决方案2】:
    import itertools
    
    x = [1,2,3,4]
    
    for each in itertools.permutations(x,2):
        print(each)
    

    请注意,itertools 是一个生成器对象,这意味着您需要遍历它才能获得所需的一切。 '2' 是可选的,但它告诉函数你想要的每个组合的数字是多少。

    You can read more here

    已编辑:

    正如 ForceBru 在评论中所说,您可以解压生成器进行打印,一起跳过 for 循环但我仍然会遍历它,因为您可能不知道生成的对象有多大:

    print(*itertools.permutations(x, 2))
    

    【讨论】:

    • 在 Python 3.x 中可以做到print(*itertools.permutations(x, 2)),甚至更短。
    • @ForceBru 好点,打开它,我想我也可以将它添加到答案中,但我认为 OP 需要生成这些肯定是有原因的(认为也许 OP 会使用它们在另一个函数调用或其他东西中)
    • @ForceBru permutations 返回一个迭代器,但我很确定解压它会创建一个(可能很大)对象,这实际上可能会减慢整个过程(尤其是如果交换变成必需)。
    • @lungj 鉴于这是一个标准库解决方案,我真的不希望您使用另一种方法获得更好的性能。
    • 除非这没有提供所需的输出。你需要itertools.combinations
    猜你喜欢
    • 2010-12-07
    • 1970-01-01
    • 2019-04-07
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多