两个非连续项目的组合

时间:2016-11-05 13:16:00

标签: python list combinations

给定一个列表,我如何获得两个非连续项之间的所有组合?

例如,对于输入[1, 2, 3, 4, 5],我如何获得输出[(1,3), (1,4), (1,5), (2,4), (2,5), (3,5)]

我对(1,2)(2,3)(3,4)(4,5)不感兴趣,因为它们在列表中是连续的(即彼此相邻),但其他一切我很感兴趣。

在Python中执行此操作最常用的方法是什么?

4 个答案:

答案 0 :(得分:5)

一个简单的列表理解:

>>> lst = [1, 2, 3, 4, 5]
>>> [(a, b) for i, a in enumerate(lst) for b in lst[i+2:]]
[(1, 3), (1, 4), (1, 5), (2, 4), (2, 5), (3, 5)]

答案 1 :(得分:3)

这是一种相当“惯用”的方式,不使用任何模块,这比其他一些实现更有效,因为每次使用循环都会被使用 - 没有被拒绝的可能性。

r = [1, 2, 3, 4, 5]
c = [(r[i], r[j]) for i in range(len(r)-2) for j in range(i+2, len(r))]
print(c)

这给出了

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

这不是完全惯用的,因为它循环于索引而不是值,但是你对列表中的位置而不是值的限制使得这非常必要。如果您想要一个生成器而不是列表,请用括号替换外括号。

答案 2 :(得分:1)

如果您对列表中包含非连续数字的组合感兴趣:

from itertools import combinations

lst = [1, 2, 3, 4, 5]
list(filter(lambda x: lst.index(x[1]) - lst.index(x[0]) > 1, combinations(lst,2)))

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

比较给定组合中两个数字的指数,并确保它们的指数差异大于1.

我希望它有所帮助。

答案 3 :(得分:1)

这是r-长度组合避免连续元素的通用解决方案。它获得所有索引combinations以获得适当缩短的列表,然后展开每个组合的索引。例如,对于r = 3,任何组合(x,y,z)都会变为使用的索引x + 0,y + 1,z + 2.

from itertools import combinations

def non_consecutive_combinations(lst, r):
    return [tuple(lst[j+i] for i, j in enumerate(combi))
            for combi in combinations(range(len(lst)-r+1), r)]

r = 2的演示:

>>> non_consecutive_combinations([1, 2, 3, 4, 5], 2)
[(1, 3), (1, 4), (1, 5), (2, 4), (2, 5), (3, 5)]

r = 3的演示:

>>> non_consecutive_combinations([1, 2, 3, 4, 5, 6, 7], 3)
[(1, 3, 5), (1, 3, 6), (1, 3, 7), (1, 4, 6), (1, 4, 7), (1, 5, 7), (2, 4, 6), (2, 4, 7), (2, 5, 7), (3, 5, 7)]

仅适用于对的简化版本:

>>> [(lst[i], lst[j+1]) for i, j in combinations(range(len(lst)-1), 2)]
[(1, 3), (1, 4), (1, 5), (2, 4), (2, 5), (3, 5)]