给定一个列表,我如何获得两个非连续项之间的所有组合?
例如,对于输入[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中执行此操作最常用的方法是什么?
答案 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)]